diff options
| author | querns <33518699+querns@users.noreply.github.com> | 2023-09-13 10:03:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-13 17:03:17 +0200 |
| commit | b31052879e7601dbfea4c7fb53b94119c7bbf5c6 (patch) | |
| tree | 69c6778c385c27ada8ec61478f5bc6da32bbc8fb /src/main/java/gregtech/common | |
| parent | 62bb20ef6271b09dab45d66103a185774aba523e (diff) | |
| download | GT5-Unofficial-b31052879e7601dbfea4c7fb53b94119c7bbf5c6.tar.gz GT5-Unofficial-b31052879e7601dbfea4c7fb53b94119c7bbf5c6.tar.bz2 GT5-Unofficial-b31052879e7601dbfea4c7fb53b94119c7bbf5c6.zip | |
Adds Metrics Transmitter Cover and Advanced GT Sensor Card for Information Panels (#2289)
* Adds several UI elements to multiblock drills
* Adds metrics transmitter cover and associated sensor card
* Fixes item icons and item name
* Adds tooltips for adv. sensor card and metrics panel, fixes card/overlay icons, adds recipe for metrics cover
* Refactor cover tab sync to send much smaller ISerializable payloads
* Remove unused variable
* Additional master merge cleanup
* Adds interface for custom metrics export, adds oil drill support
* Adds support for metrics covers retaining attached machine name for tooltip, metrics
* * Adds discrete coordinates to Metrics Cover data
* Adds machine to advanced sensor card tooltip
* Adds cycle time and minimum energy hatch tier to multiblock ore drill tooltips
* Moves many tooltip strings to i10n
* Remove old GT_DisabledWhileActiveButton.java file that crept in during a messy merge
* Spotless
* Improve oil and ore drill metrics, more i18n
* Addresses PR review concerns, adds more situations for self-destructing sensor cards
* Remediates further PR concerns
Diffstat (limited to 'src/main/java/gregtech/common')
15 files changed, 1283 insertions, 26 deletions
diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java index d853ea5f0a..2da2b883ca 100644 --- a/src/main/java/gregtech/common/GT_Proxy.java +++ b/src/main/java/gregtech/common/GT_Proxy.java @@ -166,6 +166,7 @@ import gregtech.common.entities.GT_Entity_Arrow; import gregtech.common.items.GT_MetaGenerated_Item_98; import gregtech.common.items.GT_MetaGenerated_Tool_01; import gregtech.common.misc.GlobalEnergyWorldSavedData; +import gregtech.common.misc.GlobalMetricsCoverDatabase; import gregtech.common.misc.spaceprojects.SpaceProjectWorldSavedData; public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler, IGlobalWirelessEnergy { @@ -1095,6 +1096,7 @@ public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler, IG MinecraftForge.EVENT_BUS.register(new GlobalEnergyWorldSavedData("")); MinecraftForge.EVENT_BUS.register(new SpaceProjectWorldSavedData()); MinecraftForge.EVENT_BUS.register(new GT_Worldgenerator.OregenPatternSavedData("")); + MinecraftForge.EVENT_BUS.register(new GlobalMetricsCoverDatabase()); FMLCommonHandler.instance() .bus() .register(new GT_Worldgenerator.OregenPatternSavedData("")); diff --git a/src/main/java/gregtech/common/covers/CoverInfo.java b/src/main/java/gregtech/common/covers/CoverInfo.java index e63fe6e176..0fac00218c 100644 --- a/src/main/java/gregtech/common/covers/CoverInfo.java +++ b/src/main/java/gregtech/common/covers/CoverInfo.java @@ -1,6 +1,7 @@ package gregtech.common.covers; import java.lang.ref.WeakReference; +import java.util.List; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; @@ -9,6 +10,8 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; +import org.jetbrains.annotations.NotNull; + import com.gtnewhorizons.modularui.api.screen.ModularWindow; import gregtech.api.GregTech_API; @@ -238,4 +241,9 @@ public final class CoverInfo { public int getFacadeMeta() { return getCoverBehavior().getFacadeMeta(coverSide, coverID, coverData, coveredTile.get()); } + + @NotNull + public List<String> getAdditionalTooltip(ISerializableObject data) { + return getCoverBehavior().getAdditionalTooltip(data); + } } diff --git a/src/main/java/gregtech/common/covers/GT_Cover_Metrics_Transmitter.java b/src/main/java/gregtech/common/covers/GT_Cover_Metrics_Transmitter.java new file mode 100644 index 0000000000..6d3cf529d3 --- /dev/null +++ b/src/main/java/gregtech/common/covers/GT_Cover_Metrics_Transmitter.java @@ -0,0 +1,212 @@ +package gregtech.common.covers; + +import java.util.List; +import java.util.UUID; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.ForgeDirection; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.enums.ItemList; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetricsExporter; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.util.GT_CoverBehaviorBase; +import gregtech.api.util.ISerializableObject; +import gregtech.common.events.MetricsCoverDataEvent; +import gregtech.common.events.MetricsCoverSelfDestructEvent; +import gregtech.common.misc.GlobalMetricsCoverDatabase; +import gregtech.common.misc.GlobalMetricsCoverDatabase.State; +import io.netty.buffer.ByteBuf; + +/** + * Used to transmit Nuclear Control information across dimensions. The only reason this is a cover is to artificially + * limit the number of total machines that transmit this data, for performance reasons. + * <p> + * This cover will retrieve information, preferentially, using {@link IMetricsExporter#reportMetrics()}. Absent this + * method, it will resort to {@link BaseMetaTileEntity#getInfoData()} instead. + */ +public class GT_Cover_Metrics_Transmitter + extends GT_CoverBehaviorBase<GT_Cover_Metrics_Transmitter.MetricsTransmitterData> { + + @SuppressWarnings("SpellCheckingInspection") + public static final String FREQUENCY_MSB_KEY = "gt.metricscover.freq_msb"; + @SuppressWarnings("SpellCheckingInspection") + public static final String FREQUENCY_LSB_KEY = "gt.metricscover.freq_lsb"; + public static final String MACHINE_KEY = "machine_name"; + public static final String CARD_STATE_KEY = "card_state"; + + @SuppressWarnings("unused") + public GT_Cover_Metrics_Transmitter() { + this(null); + } + + public GT_Cover_Metrics_Transmitter(ITexture coverTexture) { + super(MetricsTransmitterData.class, coverTexture); + } + + @Override + public MetricsTransmitterData createDataObject(int aLegacyData) { + // As a new cover, this shouldn't fire. + return new MetricsTransmitterData(); + } + + @Override + public MetricsTransmitterData createDataObject() { + return new MetricsTransmitterData(); + } + + @Override + protected int getTickRateImpl(ForgeDirection side, int aCoverID, MetricsTransmitterData aCoverVariable, + ICoverable aTileEntity) { + return 20; + } + + @Override + public boolean isCoverPlaceable(ForgeDirection side, ItemStack aStack, ICoverable aTileEntity) { + return aTileEntity instanceof final IGregTechDeviceInformation device && device.isGivingInformation(); + } + + @Override + protected MetricsTransmitterData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, + MetricsTransmitterData aCoverVariable, ICoverable aTileEntity, long aTimer) { + if (aTileEntity instanceof final BaseMetaTileEntity baseMTE && baseMTE.isGivingInformation()) { + final List<String> payload; + + if (baseMTE.getMetaTileEntity() instanceof final IMetricsExporter metricsExporter) { + payload = metricsExporter.reportMetrics(); + } else { + payload = ImmutableList.copyOf(baseMTE.getInfoData()); + } + + MinecraftForge.EVENT_BUS.post(new MetricsCoverDataEvent( + aCoverVariable.frequency, + payload, + new GlobalMetricsCoverDatabase.Coordinates( + baseMTE.getWorld().provider.getDimensionName(), + baseMTE.getXCoord(), + baseMTE.getYCoord(), + baseMTE.getZCoord() + ) + )); + } + + return aCoverVariable; + } + + @Override + protected void onDroppedImpl(ForgeDirection side, int aCoverID, MetricsTransmitterData aCoverVariable, + ICoverable aTileEntity) { + MinecraftForge.EVENT_BUS.post(new MetricsCoverSelfDestructEvent(aCoverVariable.frequency)); + } + + @Override + public void onPlayerAttach(EntityPlayer player, ItemStack aCover, ICoverable aTileEntity, ForgeDirection side) { + final UUID newFrequency = UUID.randomUUID(); + final ItemStack cardStack = ItemList.NC_AdvancedSensorCard.get(1); + + if (cardStack == null) { + return; + } + + final NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setLong(FREQUENCY_MSB_KEY, newFrequency.getMostSignificantBits()); + tagCompound.setLong(FREQUENCY_LSB_KEY, newFrequency.getLeastSignificantBits()); + tagCompound.setInteger(CARD_STATE_KEY, State.OPERATIONAL.getType()); + + if (aTileEntity instanceof final BaseMetaTileEntity baseMTE) { + final ItemStack baseMTEStack = baseMTE.getStackForm(1); + if (baseMTEStack != null) { + tagCompound.setTag(MACHINE_KEY, baseMTEStack.writeToNBT(new NBTTagCompound())); + } + } + + cardStack.setTagCompound(tagCompound); + aTileEntity.getCoverInfoAtSide(side) + .setCoverData(new MetricsTransmitterData(newFrequency)); + + final EntityItem cardEntity = new EntityItem(player.worldObj, player.posX, player.posY, player.posZ, cardStack); + cardEntity.delayBeforeCanPickup = 0; + player.worldObj.spawnEntityInWorld(cardEntity); + } + + @Override + public boolean allowsCopyPasteTool() { + return false; + } + + @Override + public List<String> getAdditionalTooltipImpl(MetricsTransmitterData data) { + return ImmutableList.of( + StatCollector.translateToLocalFormatted( + "gt.item.adv_sensor_card.tooltip.frequency", + EnumChatFormatting.UNDERLINE.toString() + EnumChatFormatting.YELLOW + data.frequency.toString())); + } + + public static class MetricsTransmitterData implements ISerializableObject { + + private UUID frequency; + + public MetricsTransmitterData() { + this.frequency = UUID.randomUUID(); + } + + public MetricsTransmitterData(@NotNull UUID frequency) { + this.frequency = frequency; + } + + @NotNull + public UUID getFrequency() { + return frequency; + } + + @NotNull + @Override + public ISerializableObject copy() { + return new MetricsTransmitterData(frequency); + } + + @NotNull + @Override + public NBTBase saveDataToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setLong(FREQUENCY_MSB_KEY, frequency.getMostSignificantBits()); + tag.setLong(FREQUENCY_LSB_KEY, frequency.getLeastSignificantBits()); + return tag; + } + + @Override + public void loadDataFromNBT(NBTBase aNBT) { + if (aNBT instanceof final NBTTagCompound tag) { + frequency = new UUID(tag.getLong(FREQUENCY_MSB_KEY), tag.getLong(FREQUENCY_LSB_KEY)); + } + } + + @Override + public void writeToByteBuf(ByteBuf aBuf) { + aBuf.writeLong(frequency.getMostSignificantBits()); + aBuf.writeLong(frequency.getLeastSignificantBits()); + } + + @NotNull + @Override + public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, @Nullable EntityPlayerMP aPlayer) { + return new MetricsTransmitterData(new UUID(aBuf.readLong(), aBuf.readLong())); + } + } +} diff --git a/src/main/java/gregtech/common/events/BaseMetricsCoverEvent.java b/src/main/java/gregtech/common/events/BaseMetricsCoverEvent.java new file mode 100644 index 0000000000..953d6fbfcf --- /dev/null +++ b/src/main/java/gregtech/common/events/BaseMetricsCoverEvent.java @@ -0,0 +1,21 @@ +package gregtech.common.events; + +import java.util.UUID; + +import org.jetbrains.annotations.NotNull; + +import cpw.mods.fml.common.eventhandler.Event; + +public abstract class BaseMetricsCoverEvent extends Event { + + protected final UUID frequency; + + public BaseMetricsCoverEvent(@NotNull UUID frequency) { + this.frequency = frequency; + } + + @NotNull + public UUID getFrequency() { + return frequency; + } +} diff --git a/src/main/java/gregtech/common/events/MetricsCoverDataEvent.java b/src/main/java/gregtech/common/events/MetricsCoverDataEvent.java new file mode 100644 index 0000000000..92a5aa663a --- /dev/null +++ b/src/main/java/gregtech/common/events/MetricsCoverDataEvent.java @@ -0,0 +1,37 @@ +package gregtech.common.events; + +import java.util.List; +import java.util.UUID; + +import org.jetbrains.annotations.NotNull; + +import gregtech.common.misc.GlobalMetricsCoverDatabase; + +/** + * Event fired when the Metrics Transmitter cover sends an information packet. + */ +public class MetricsCoverDataEvent extends BaseMetricsCoverEvent { + + @NotNull + private final List<String> payload; + + @NotNull + private final GlobalMetricsCoverDatabase.Coordinates coordinates; + + public MetricsCoverDataEvent(@NotNull UUID frequency, @NotNull List<String> payload, + @NotNull GlobalMetricsCoverDatabase.Coordinates coordinates) { + super(frequency); + this.payload = payload; + this.coordinates = coordinates; + } + + @NotNull + public List<String> getPayload() { + return payload; + } + + @NotNull + public GlobalMetricsCoverDatabase.Coordinates getCoordinates() { + return coordinates; + } +} diff --git a/src/main/java/gregtech/common/events/MetricsCoverHostDeconstructedEvent.java b/src/main/java/gregtech/common/events/MetricsCoverHostDeconstructedEvent.java new file mode 100644 index 0000000000..490bd7d0b0 --- /dev/null +++ b/src/main/java/gregtech/common/events/MetricsCoverHostDeconstructedEvent.java @@ -0,0 +1,16 @@ +package gregtech.common.events; + +import java.util.UUID; + +import org.jetbrains.annotations.NotNull; + +/** + * Event fired when the machine housing a Metrics Transmitter cover is deconstructed, but the cover remains + * attached. + */ +public class MetricsCoverHostDeconstructedEvent extends BaseMetricsCoverEvent { + + public MetricsCoverHostDeconstructedEvent(@NotNull UUID frequency) { + super(frequency); + } +} diff --git a/src/main/java/gregtech/common/events/MetricsCoverSelfDestructEvent.java b/src/main/java/gregtech/common/events/MetricsCoverSelfDestructEvent.java new file mode 100644 index 0000000000..d554cbcc2b --- /dev/null +++ b/src/main/java/gregtech/common/events/MetricsCoverSelfDestructEvent.java @@ -0,0 +1,15 @@ +package gregtech.common.events; + +import java.util.UUID; + +import org.jetbrains.annotations.NotNull; + +/** + * Event fired when a Metrics Transmitter cover is detached from its machine with a crowbar. + */ +public class MetricsCoverSelfDestructEvent extends BaseMetricsCoverEvent { + + public MetricsCoverSelfDestructEvent(@NotNull UUID frequency) { + super(frequency); + } +} diff --git a/src/main/java/gregtech/common/items/GT_AdvancedSensorCard_Item.java b/src/main/java/gregtech/common/items/GT_AdvancedSensorCard_Item.java new file mode 100644 index 0000000000..820fe59952 --- /dev/null +++ b/src/main/java/gregtech/common/items/GT_AdvancedSensorCard_Item.java @@ -0,0 +1,323 @@ +package gregtech.common.items; + +import static gregtech.api.enums.Mods.GregTech; +import static gregtech.common.covers.GT_Cover_Metrics_Transmitter.CARD_STATE_KEY; +import static gregtech.common.covers.GT_Cover_Metrics_Transmitter.FREQUENCY_LSB_KEY; +import static gregtech.common.covers.GT_Cover_Metrics_Transmitter.FREQUENCY_MSB_KEY; +import static gregtech.common.covers.GT_Cover_Metrics_Transmitter.MACHINE_KEY; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; + +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.common.misc.GlobalMetricsCoverDatabase; +import gregtech.common.misc.GlobalMetricsCoverDatabase.State; +import shedar.mods.ic2.nuclearcontrol.api.CardState; +import shedar.mods.ic2.nuclearcontrol.api.ICardWrapper; +import shedar.mods.ic2.nuclearcontrol.api.IPanelDataSource; +import shedar.mods.ic2.nuclearcontrol.api.PanelSetting; +import shedar.mods.ic2.nuclearcontrol.api.PanelString; + +@SuppressWarnings("unused") +public class GT_AdvancedSensorCard_Item extends Item implements IPanelDataSource { + + public static final UUID CARD_TYPE_ID = UUID.fromString("ff952e84-7608-4c4a-85af-dd6e1aa27fc7"); + + // This has obfuscated formatting, so no need to localize it. + private static final ImmutableList<PanelString> SELF_DESTRUCTED_OUTPUT = ImmutableList + .of(prebakePanelString(EnumChatFormatting.OBFUSCATED + "critical error" + EnumChatFormatting.RESET, true)); + + private static final ImmutableList<PanelString> DECONSTRUCTED_OUTPUT = ImmutableList.of( + prebakePanelString(StatCollector.translateToLocal("gt.item.adv_sensor_card.error.deconstructed.1"), true), + prebakePanelString(StatCollector.translateToLocal("gt.item.adv_sensor_card.error.deconstructed.2"), true)); + + private static final ImmutableList<PanelString> NO_DATA_FOUND = ImmutableList + .of(prebakePanelString(StatCollector.translateToLocal("gt.item.adv_sensor_card.error.no_data"), true)); + + private int payloadSize = 0; + + @SideOnly(Side.CLIENT) + private IIcon normalIcon; + @SideOnly(Side.CLIENT) + private IIcon selfDestructedIcon; + + @SuppressWarnings("unused") + public GT_AdvancedSensorCard_Item() { + super(); + + GameRegistry.registerItem(this, "gt.advancedsensorcard", GregTech.ID); + setUnlocalizedName("gt.advancedsensorcard"); + setMaxStackSize(1); + setNoRepair(); + } + + @Override + public void addInformation(final ItemStack itemStack, final EntityPlayer player, final List<String> tooltip, + final boolean p_77624_4_) { + super.addInformation(itemStack, player, tooltip, p_77624_4_); + + final Optional<State> cardState = getCardState(itemStack); + if (cardState.isPresent()) { + final State state = cardState.get(); + + if (state == State.SELF_DESTRUCTED) { + tooltip.add(StatCollector.translateToLocal("gt.item.adv_sensor_card.tooltip.fried.1")); + tooltip.add(StatCollector.translateToLocal("gt.item.adv_sensor_card.tooltip.fried.2")); + tooltip.add(StatCollector.translateToLocal("gt.item.adv_sensor_card.tooltip.fried.3")); + } else { + getMachineName(itemStack).ifPresent( + machineName -> tooltip.add( + StatCollector + .translateToLocalFormatted("gt.item.adv_sensor_card.tooltip.machine", machineName))); + getUUID(itemStack).ifPresent( + uuid -> tooltip.add( + StatCollector + .translateToLocalFormatted("gt.item.adv_sensor_card.tooltip.frequency", uuid.toString()))); + } + } else { + tooltip.add(StatCollector.translateToLocal("gt.item.adv_sensor_card.tooltip.recipe_hint")); + } + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item aItem, CreativeTabs aCreativeTab, List<ItemStack> aOutputSubItems) {} + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(final IIconRegister aIconRegister) { + super.registerIcons(aIconRegister); + itemIcon = aIconRegister.registerIcon(GregTech.ID + ":gt.advancedsensorcard"); + normalIcon = itemIcon; + selfDestructedIcon = aIconRegister.registerIcon(GregTech.ID + ":gt.advancedsensorcardburned"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(final ItemStack stack, final int renderPass) { + return getIconIndex(stack); + } + + @Override + public IIcon getIconIndex(final ItemStack itemStack) { + return getCardState(itemStack).filter(Predicate.isEqual(State.SELF_DESTRUCTED)) + .map(ignored -> selfDestructedIcon) + .orElse(normalIcon); + } + + @Override + public CardState update(TileEntity tileEntity, ICardWrapper card, int maxRange) { + return update(tileEntity.getWorldObj(), card, maxRange); + } + + @Override + public CardState update(World world, ICardWrapper card, int maxRange) { + getDataFromDatabase(card).ifPresent(data -> { + reconcileSelfDestructedCard(card.getItemStack(), data.getState()); + card.setInt( + CARD_STATE_KEY, + data.getState() + .getType()); + payloadSize = switch (data.getState()) { + case SELF_DESTRUCTED -> SELF_DESTRUCTED_OUTPUT.size(); + case HOST_DECONSTRUCTED -> DECONSTRUCTED_OUTPUT.size() + getMachineName(card.getItemStack()).map(x -> 1) + .orElse(0); + case OPERATIONAL -> data.getPayload() + .map(List::size) + .orElse(0) + + getMachineName(card.getItemStack()).map(x -> 1) + .orElse(0) + + data.getCoordinates() + .map(x -> 2) + .orElse(0); + }; + }); + return CardState.OK; + } + + @Override + public List<PanelString> getStringData(final int displaySettings, final ICardWrapper card, + final boolean showLabels) { + // This method needs to return a mutable list, since the calling routine in NuclearCraft appends an item to the + // head of the list. Hence, all the array copying. + + return getCardState(card).map(state -> switch (state) { + case SELF_DESTRUCTED -> new ArrayList<>(SELF_DESTRUCTED_OUTPUT); + case HOST_DECONSTRUCTED -> { + final ArrayList<PanelString> list = new ArrayList<>(); + getMachineName(card.getItemStack()).ifPresent(name -> list.add(prebakePanelString(name, true))); + list.addAll(DECONSTRUCTED_OUTPUT); + yield list; + } + case OPERATIONAL -> getDataFromDatabase(card).map(data -> { + final ImmutableList.Builder<String> builder = ImmutableList.builder(); + + getMachineName(card.getItemStack()).ifPresent(builder::add); + data.getCoordinates() + .ifPresent( + coordinates -> builder.add( + StatCollector.translateToLocalFormatted( + "gt.item.adv_sensor_card.dimension", + coordinates.getDimension()), + StatCollector.translateToLocalFormatted( + "gt.item.adv_sensor_card.coords", + coordinates.getLocalizedCoordinates()))); + + data.getPayload() + .ifPresent(builder::addAll); + + return builder.build(); + }) + .filter(payload -> !payload.isEmpty()) + .map( + payload -> IntStream.range(0, payload.size()) + .filter(i -> (displaySettings & (1 << i)) != 0) + .mapToObj(i -> prebakePanelString(payload.get(i), i == 0)) + .collect(Collectors.toCollection(ArrayList::new))) + .orElse(null); + }) + .orElse(new ArrayList<>(NO_DATA_FOUND)); + } + + @Override + public List<PanelSetting> getSettingsList() { + return payloadSize == 0 ? ImmutableList.of() + : ImmutableList.copyOf( + IntStream.range(0, Math.min(payloadSize, 31)) + .mapToObj(i -> new PanelSetting(String.valueOf(i + 1), 1 << i, getCardType())) + .iterator()); + } + + @Override + public UUID getCardType() { + return CARD_TYPE_ID; + } + + @Override + public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int slot, boolean isHeld) { + super.onUpdate(stack, worldIn, entityIn, slot, isHeld); + // At the time of this comment's writing, there are 52 matches of the regex: + // /% \d+0 \)?\s*== 0/ in the code base, indicating an over-reliance on events happening on either the 10th or + // 20th tick. Let's tick on something slightly off of that. A prime number will do nicely. + if ((worldIn.getWorldTime() % 20) == 13) { + getDataFromDatabase(stack).ifPresent(data -> { + reconcileSelfDestructedCard(stack, data.getState()); + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); + } + + stack.getTagCompound() + .setInteger( + CARD_STATE_KEY, + data.getState() + .getType()); + }); + } + } + + private void reconcileSelfDestructedCard(ItemStack stack, State newState) { + getUUID(stack).ifPresent(uuid -> getCardState(stack).ifPresent(oldState -> { + if (newState == State.SELF_DESTRUCTED && oldState != State.SELF_DESTRUCTED) { + GlobalMetricsCoverDatabase.clearSelfDestructedFrequency(uuid); + } + })); + + } + + @NotNull + private Optional<State> getCardState(ICardWrapper card) { + return getCardState(card.getItemStack()); + } + + @NotNull + private Optional<State> getCardState(ItemStack itemStack) { + if (itemStack.hasTagCompound() && itemStack.getTagCompound() + .hasKey(CARD_STATE_KEY)) { + return State.find( + itemStack.getTagCompound() + .getInteger(CARD_STATE_KEY)); + } + + return Optional.empty(); + } + + @NotNull + private Optional<UUID> getUUID(ItemStack stack) { + if (stack.hasTagCompound()) { + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt.hasKey(FREQUENCY_LSB_KEY) && nbt.hasKey(FREQUENCY_MSB_KEY)) { + return Optional.of(new UUID(nbt.getLong(FREQUENCY_MSB_KEY), nbt.getLong(FREQUENCY_LSB_KEY))); + } + } + + return Optional.empty(); + } + + @NotNull + private Optional<String> getMachineName(ItemStack stack) { + if (stack.hasTagCompound() && stack.getTagCompound() + .hasKey(MACHINE_KEY)) { + try { + final ItemStack machine = ItemStack.loadItemStackFromNBT( + stack.getTagCompound() + .getCompoundTag(MACHINE_KEY)); + if (machine != null) { + return Optional.of(machine.getDisplayName()); + } + } catch (Exception ignored) {} + } + + return Optional.empty(); + } + + @NotNull + private Optional<GlobalMetricsCoverDatabase.Data> getDataFromDatabase(ICardWrapper card) { + return getDataFromDatabase(card.getItemStack()); + } + + @NotNull + private Optional<GlobalMetricsCoverDatabase.Data> getDataFromDatabase(ItemStack stack) { + return getUUID(stack).flatMap(GlobalMetricsCoverDatabase::getData); + } + + @NotNull + private static PanelString prebakePanelString(String info) { + return prebakePanelString(info, false); + } + + @NotNull + private static PanelString prebakePanelString(String info, boolean center) { + final PanelString panelString = new PanelString(); + if (center) { + panelString.textCenter = info; + } else { + panelString.textLeft = info; + } + return panelString; + + } +} diff --git a/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_03.java b/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_03.java index bede46adc9..f980c8031b 100644 --- a/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_03.java +++ b/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_03.java @@ -1,5 +1,7 @@ package gregtech.common.items; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_METRICS_TRANSMITTER; import static gregtech.api.enums.Textures.BlockIcons.SOLARPANEL_UEV; import static gregtech.api.enums.Textures.BlockIcons.SOLARPANEL_UHV; import static gregtech.api.enums.Textures.BlockIcons.SOLARPANEL_UIV; @@ -21,6 +23,7 @@ import static gregtech.client.GT_TooltipHandler.Tier.ZPM; import static gregtech.client.GT_TooltipHandler.registerTieredTooltip; import gregtech.api.GregTech_API; +import gregtech.api.enums.GT_Values; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; @@ -29,6 +32,7 @@ import gregtech.api.enums.TC_Aspects; import gregtech.api.items.GT_MetaGenerated_Item_X32; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_OreDictUnificator; +import gregtech.common.covers.GT_Cover_Metrics_Transmitter; import gregtech.common.covers.GT_Cover_SolarPanel; public class GT_MetaGenerated_Item_03 extends GT_MetaGenerated_Item_X32 { @@ -911,6 +915,22 @@ public class GT_MetaGenerated_Item_03 extends GT_MetaGenerated_Item_X32 { "By the powers of Greg, I command this star to be really hot.", SubTag.NO_UNIFICATION)); + ItemList.Cover_Metrics_Transmitter.set( + addItem( + 232, + "Metrics Transmitter Cover", + String.join( + "/n ", + "Taking Information Panels to the next level!", + "Creates a GregTech Advanced Sensor Card when attached", + "Works across dimensions or if machine is dismantled", + "Removing this cover will destroy the linked card", + GT_Values.AuthorQuerns))); + GregTech_API.registerCover( + ItemList.Cover_Metrics_Transmitter.get(1L), + TextureFactory.of(MACHINE_CASINGS[2][0], TextureFactory.of(OVERLAY_METRICS_TRANSMITTER)), + new GT_Cover_Metrics_Transmitter(TextureFactory.of(OVERLAY_METRICS_TRANSMITTER))); + ItemList.Optical_Cpu_Containment_Housing.set(addItem(727, "Optical CPU Containment Housing", "CPU Housing", o)); ItemList.Optically_Perfected_CPU.set(addItem(726, "Optically Perfected CPU", "Perfected CPU!", o)); ItemList.Optically_Compatible_Memory.set(addItem(725, "Optically Compatible Memory", "Its in the name!", o)); diff --git a/src/main/java/gregtech/common/items/GT_SensorCard_Item.java b/src/ma |
