diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 018ae8c5a..8676059a8 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -836,6 +836,15 @@ "create.gui.stressometer.capacity": "Remaining Capacity", "create.gui.stressometer.overstressed": "Overstressed", "create.gui.stressometer.no_rotation": "No Rotation", + "create.gui.stores_fluid.title": "Fluid Contained", + "create.gui.stores_fluid.effectsTitle": "Potion Effects", + "create.gui.stores_fluid.empty": "Empty", + "create.gui.input_tanks.title": "Input Tanks", + "create.gui.output_tanks.title": "Output Tanks", + "create.gui.tank.info_header": "Tank Information:", + "create.gui.spout.info_header": "Spout Information:", + "create.gui.drain.info_header": "Drain Information:", + "create.gui.basin.info_header": "Basin Information:", "create.gui.contraptions.not_fast_enough": "It appears that this %1$s is _not_ rotating with _enough_ _speed_.", "create.gui.contraptions.network_overstressed": "It appears that this contraption is _overstressed_. Add more sources or _slow_ _down_ the components with a high _stress_ _impact_.", "create.gui.adjustable_crate.title": "Adjustable Crate", @@ -1064,6 +1073,10 @@ "create.tooltip.stressImpact.medium": "Moderate", "create.tooltip.stressImpact.high": "High", "create.tooltip.stressImpact.overstressed": "Overstressed", + "create.tooltip.fluidFullness.low": "Low", + "create.tooltip.fluidFullness.medium": "Moderate", + "create.tooltip.fluidFullness.high": "High", + "create.tooltip.fluidFullness.full": "Full", "create.tooltip.capacityProvided": "Stress Capacity: %1$s", "create.tooltip.capacityProvided.low": "Small", "create.tooltip.capacityProvided.medium": "Medium", @@ -1446,6 +1459,8 @@ "item.create.goggles.tooltip.behaviour1": "Shows _colored indicators_ corresponding to the _Speed Level_ of a placed kinetic component as well as _Stress Impact_ and _Capacity_ of individual components.", "item.create.goggles.tooltip.condition2": "When looking at gauge", "item.create.goggles.tooltip.behaviour2": "Shows detailed information about _Speed_ or _Stress_ of the network to which the gauge is connected.", + "item.create.goggles.tooltip.condition3": "When looking at fluid containers", + "item.create.goggles.tooltip.behaviour3": "Shows detailed information about the _Capacity_ of the block and any _Fluids_ stored within.", "item.create.wrench.tooltip": "WRENCH", "item.create.wrench.tooltip.summary": "A useful tool for working on kinetic contraptions. Can be used to _Rotate_, _Dismantle_ and to _Configure_ components.", diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFullnessOverlay.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFullnessOverlay.java new file mode 100644 index 000000000..a1604e4c6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFullnessOverlay.java @@ -0,0 +1,73 @@ +package com.simibubi.create.content.contraptions.fluids; + +import com.simibubi.create.AllFluids; +import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler; +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; +import com.simibubi.create.foundation.item.ItemDescription; +import com.simibubi.create.foundation.utility.Lang; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fluids.FluidStack; + + +//Currently only used for Tank/Drain/Spout/Basin goggle tooltips, as fullness-based replacement for the stress-based tooltips in IRotate +public enum FluidFullnessOverlay { + LOW, + MEDIUM, + HIGH, + FULL; + + public TextFormatting getAbsoluteColor() { + return this == LOW ? TextFormatting.YELLOW : this == MEDIUM ? TextFormatting.GOLD : TextFormatting.RED; + } + + public TextFormatting getRelativeColor() { + return this == LOW ? TextFormatting.GREEN : this == MEDIUM ? TextFormatting.YELLOW : this == HIGH ? TextFormatting.GOLD : TextFormatting.RED; + } + + public static FluidFullnessOverlay of(double fullnessPercent){ + if (fullnessPercent >= 1) return FluidFullnessOverlay.FULL; + else if (fullnessPercent > .75d) return FluidFullnessOverlay.HIGH; + else if (fullnessPercent > .5d) return FluidFullnessOverlay.MEDIUM; + else return FluidFullnessOverlay.LOW; + } + + public static String getFormattedFullnessText(double fullnessPercent){ + FluidFullnessOverlay fullnessLevel = of(fullnessPercent); + TextFormatting color = fullnessLevel.getRelativeColor(); + if (fullnessPercent == 0) + return TextFormatting.DARK_GRAY + ItemDescription.makeProgressBar(3, -1) + + Lang.translate("gui.stores_fluid.empty"); + + String level = color + ItemDescription.makeProgressBar(3, Math.min(fullnessLevel.ordinal(), 2)); + level += Lang.translate("tooltip.fluidFullness."+Lang.asId(fullnessLevel.name())); + + level += String.format(" (%s%%) ", (int) (fullnessPercent * 100)); + + return level; + } + + public static String getFormattedCapacityText(int amount, int capacity){ + FluidFullnessOverlay fullnessLevel = of((double) amount / capacity); + TextFormatting color = fullnessLevel.getRelativeColor(); + + String mb = Lang.translate("generic.unit.millibuckets"); + String capacityString = color + "%s" + mb + TextFormatting.GRAY + " / " + TextFormatting.DARK_GRAY + "%s" + mb; + + if (amount == 0) + return TextFormatting.DARK_GRAY + IHaveGoggleInformation.format(capacity) + mb; + + return String.format(capacityString, IHaveGoggleInformation.format(amount), IHaveGoggleInformation.format(capacity)); + } + + public static String getFormattedFluidTypeText(FluidStack fluid, double fullnessPercent){ + FluidFullnessOverlay fullnessLevel = of(fullnessPercent); + TextFormatting color = fullnessLevel.getRelativeColor(); + + if (AllFluids.POTION.get().getFluid().isEquivalentTo(fluid.getFluid())) { + return color + PotionFluidHandler.getPotionName(fluid).getFormattedText(); + } else { + return color + fluid.getDisplayName().getFormattedText(); + } + } + } + diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainBlock.java index 16f2a9470..2d12c3fc9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainBlock.java @@ -99,4 +99,19 @@ public class ItemDrainBlock extends Block implements IWrenchable, ITE> itemHandlers; public ItemDrainTileEntity(TileEntityType tileEntityTypeIn) { @@ -90,6 +101,13 @@ public class ItemDrainTileEntity extends SmartTileEntity { @Override public void tick() { super.tick(); + + if (lastRedstoneLevel != getComparatorOutput()) { + lastRedstoneLevel = getComparatorOutput(); + if (world != null) + world.updateComparatorOutputLevel(getPos(), getBlockState().getBlock()); + } + if (heldItem == null) { processingTicks = 0; return; @@ -278,4 +296,43 @@ public class ItemDrainTileEntity extends SmartTileEntity { return super.getCapability(cap, side); } + public int getComparatorOutput() { + ItemDrainTileEntity te = this; + double fillFraction = (double) te.internalTank.getPrimaryHandler().getFluidAmount() / te.internalTank.getPrimaryHandler().getCapacity(); + return MathHelper.floor(MathHelper.clamp(fillFraction * 14 + (fillFraction > 0 ? 1 : 0), 0, 15)); + } + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + ItemDrainTileEntity te = this; + + int fluidAmount = te.internalTank.getPrimaryHandler().getFluidAmount(); + int fluidCapacity = te.internalTank.getPrimaryHandler().getCapacity(); + double fillFraction = (double) fluidAmount / fluidCapacity; + FluidStack fluidType = te.internalTank.getPrimaryHandler().getFluid(); + + tooltip.add(spacing + Lang.translate("gui.drain.info_header")); + + if (isPlayerSneaking && AllFluids.POTION.get().getFluid().isEquivalentTo(fluidType.getFluid())) { + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.effectsTitle")); + + ArrayList potionTooltip = new ArrayList<>(); + PotionFluidHandler.addPotionTooltip(fluidType, potionTooltip, 1); + tooltip.addAll(2, potionTooltip.stream() + .map(c -> spacing + " " + c.getFormattedText()) + .collect(Collectors.toList())); + return true; + } + + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.title")); + + if (fluidAmount != 0) + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedFluidTypeText(fluidType, fillFraction)); + + tooltip.add(spacing + FluidFullnessOverlay.getFormattedFullnessText(fillFraction)); + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedCapacityText(fluidAmount, fluidCapacity)); + + return true; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutBlock.java index f7436a0a7..bb97ddac8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutBlock.java @@ -11,6 +11,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; public class SpoutBlock extends Block implements IWrenchable { @@ -34,4 +35,19 @@ public class SpoutBlock extends Block implements IWrenchable { return AllTileEntities.SPOUT.create(); } + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + TileEntity te = worldIn.getTileEntity(pos); + if (te == null) + return 0; + if (te instanceof SpoutTileEntity) + return ((SpoutTileEntity) te).getComparatorOutput(); + return 0; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java index 33c31cc95..e7ede91af 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java @@ -5,8 +5,13 @@ import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProce import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import com.simibubi.create.AllFluids; +import com.simibubi.create.content.contraptions.fluids.FluidFullnessOverlay; import com.simibubi.create.content.contraptions.fluids.FluidFX; +import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler; +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; @@ -16,6 +21,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBe import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.item.ItemStack; @@ -26,7 +32,10 @@ import net.minecraft.potion.PotionUtils; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.capabilities.Capability; @@ -34,13 +43,14 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -public class SpoutTileEntity extends SmartTileEntity { +public class SpoutTileEntity extends SmartTileEntity implements IHaveGoggleInformation { public static final int FILLING_TIME = 20; protected BeltProcessingBehaviour beltProcessing; protected int processingTicks; protected boolean sendSplash; + protected int lastRedstoneLevel; SmartFluidTankBehaviour tank; @@ -168,6 +178,12 @@ public class SpoutTileEntity extends SmartTileEntity { if (processingTicks >= 8 && world.isRemote) spawnProcessingParticles(tank.getPrimaryTank() .getRenderedFluid()); + + if (lastRedstoneLevel != getComparatorOutput()) { + lastRedstoneLevel = getComparatorOutput(); + if (world != null) + world.updateComparatorOutputLevel(getPos(), getBlockState().getBlock()); + } } protected void spawnProcessingParticles(FluidStack fluid) { @@ -190,4 +206,43 @@ public class SpoutTileEntity extends SmartTileEntity { } } + public int getComparatorOutput() { + SpoutTileEntity te = this; + double fillFraction = (double) te.getCurrentFluidInTank().getAmount() / te.tank.getPrimaryHandler().getCapacity(); + return MathHelper.floor(MathHelper.clamp(fillFraction * 14 + (fillFraction > 0 ? 1 : 0), 0, 15)); + } + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + SpoutTileEntity te = this; + + int fluidAmount = te.tank.getPrimaryHandler().getFluidAmount(); + int fluidCapacity = te.tank.getPrimaryHandler().getCapacity(); + double fillFraction = (double) fluidAmount / fluidCapacity; + FluidStack fluidType = te.tank.getPrimaryHandler().getFluid(); + + tooltip.add(spacing + Lang.translate("gui.spout.info_header")); + + if (isPlayerSneaking && AllFluids.POTION.get().getFluid().isEquivalentTo(fluidType.getFluid())) { + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.effectsTitle")); + + ArrayList potionTooltip = new ArrayList<>(); + PotionFluidHandler.addPotionTooltip(fluidType, potionTooltip, 1); + tooltip.addAll(2, potionTooltip.stream() + .map(c -> spacing + " " + c.getFormattedText()) + .collect(Collectors.toList())); + return true; + } + + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.title")); + + if (fluidAmount != 0) + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedFluidTypeText(fluidType, fillFraction)); + + tooltip.add(spacing + FluidFullnessOverlay.getFormattedFullnessText(fillFraction)); + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedCapacityText(fluidAmount, fluidCapacity)); + + return true; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java index 7a8346118..959272e27 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java @@ -310,4 +310,22 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE 0 ? 1 : 0), 0, 15)); + } + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + FluidTankTileEntity controllerTE = getControllerTE(); + if (controllerTE == null) + return false; + int fluidAmount = controllerTE.getTankInventory().getFluidAmount(); + int fluidCapacity = controllerTE.getTankInventory().getCapacity(); + double fillFraction = controllerTE.getFillState(); + FluidStack fluidType = controllerTE.getTankInventory().getFluid(); + + tooltip.add(spacing + Lang.translate("gui.tank.info_header")); + + if (isPlayerSneaking && AllFluids.POTION.get().getFluid().isEquivalentTo(fluidType.getFluid())) { + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.effectsTitle")); + + ArrayList potionTooltip = new ArrayList<>(); + PotionFluidHandler.addPotionTooltip(fluidType, potionTooltip, 1); + tooltip.addAll(2, potionTooltip.stream() + .map(c -> spacing + " " + c.getFormattedText()) + .collect(Collectors.toList())); + return true; + } + + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stores_fluid.title")); + + if (fluidAmount != 0) + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedFluidTypeText(fluidType, fillFraction)); + + tooltip.add(spacing + FluidFullnessOverlay.getFormattedFullnessText(fillFraction)); + tooltip.add(spacing + " " + FluidFullnessOverlay.getFormattedCapacityText(fluidAmount, fluidCapacity)); + + return true; + } + @Override protected void read(CompoundNBT compound, boolean clientPacket) { super.read(compound, clientPacket); diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java index 60117276f..e1afa75c0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java @@ -9,11 +9,15 @@ import java.util.Random; import javax.annotation.Nonnull; +import com.simibubi.create.AllFluids; import com.simibubi.create.AllParticleTypes; import com.simibubi.create.AllTags; +import com.simibubi.create.content.contraptions.fluids.FluidFullnessOverlay; import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerTileEntity; import com.simibubi.create.content.contraptions.fluids.FluidFX; import com.simibubi.create.content.contraptions.fluids.particle.FluidParticleData; +import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler; +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.fluid.CombinedTankWrapper; @@ -25,14 +29,8 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputB import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment; -import com.simibubi.create.foundation.utility.AnimationTickHolder; -import com.simibubi.create.foundation.utility.Couple; -import com.simibubi.create.foundation.utility.IntAttached; -import com.simibubi.create.foundation.utility.Iterate; -import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.*; import com.simibubi.create.foundation.utility.LerpedFloat.Chaser; -import com.simibubi.create.foundation.utility.NBTHelper; -import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -48,6 +46,7 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.TextFormatting; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.capabilities.Capability; @@ -63,7 +62,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.wrapper.CombinedInvWrapper; -public class BasinTileEntity extends SmartTileEntity { +public class BasinTileEntity extends SmartTileEntity implements IHaveGoggleInformation { private boolean areFluidsMoving; LerpedFloat ingredientRotationSpeed; @@ -600,6 +599,66 @@ public class BasinTileEntity extends SmartTileEntity { return areFluidsMoving; } + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + + tooltip.add(spacing + Lang.translate("gui.basin.info_header")); + + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.input_tanks.title")); + + String mb = Lang.translate("generic.unit.millibuckets"); + + LazyOptional capability = this.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); + IFluidHandler tank = capability.orElse(null); + + if (tank == null) + return false; + + for (int i = 0; i < tank.getTanks(); i += 2) { + Couple fluids = Couple.create(tank.getFluidInTank(i), tank.getFluidInTank(i + 1)); + + if (i > 1) + tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.output_tanks.title")); + + if (fluids.getFirst().getAmount() == 0 && fluids.getSecond().getAmount() == 0) { + tooltip.add(spacing + " " + TextFormatting.DARK_GRAY + "2x0" + mb); + continue; + } + + for (FluidStack fluid : fluids) { + String fluidName; + + if (fluid.getAmount() == 0) { + tooltip.add(spacing + " " + TextFormatting.DARK_GRAY + IHaveGoggleInformation.format(0) + mb); + } else { + if (AllFluids.POTION.get().getFluid().isEquivalentTo(fluid.getFluid())) { + fluidName = PotionFluidHandler.getPotionName(fluid).getFormattedText(); + } else { + fluidName = fluid.getDisplayName().getFormattedText(); + } + double fillFraction = (double) fluid.getAmount() / (double) this.inputTank.getPrimaryHandler().getCapacity(); + if (fluidName.length() > 15) { + tooltip.add(spacing + " " + FluidFullnessOverlay.of(fillFraction).getRelativeColor() + + fluidName); + tooltip.add(spacing + " " + FluidFullnessOverlay.of(fillFraction).getRelativeColor() + + IHaveGoggleInformation.format(fluid.getAmount()) + mb); + continue; + } + + tooltip.add(spacing + " " + FluidFullnessOverlay.of(fillFraction).getRelativeColor() + + fluidName + " " + + IHaveGoggleInformation.format(fluid.getAmount()) + mb); + + } + } + + + + + } + return true; + } + class BasinValueBox extends ValueBoxTransform.Sided { @Override