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/items | |
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/items')
4 files changed, 360 insertions, 9 deletions
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/main/java/gregtech/common/items/GT_SensorCard_Item.java index 024b089812..67e5b24a70 100644 --- a/src/main/java/gregtech/common/items/GT_SensorCard_Item.java +++ b/src/main/java/gregtech/common/items/GT_SensorCard_Item.java @@ -43,7 +43,7 @@ public class GT_SensorCard_Item extends GT_Generic_Item implements IRemoteSensor if (aStack != null) { NBTTagCompound tNBT = aStack.getTagCompound(); if (tNBT == null) { - aList.add(transItem("014", "Missing Coodinates!")); + aList.add(transItem("014", "Missing Coordinates!")); } else { aList.add(transItem("015", "Device at:")); aList.add( diff --git a/src/main/java/gregtech/common/items/behaviors/Behaviour_Cover_Tool.java b/src/main/java/gregtech/common/items/behaviors/Behaviour_Cover_Tool.java index bb37e1e933..5688872796 100644 --- a/src/main/java/gregtech/common/items/behaviors/Behaviour_Cover_Tool.java +++ b/src/main/java/gregtech/common/items/behaviors/Behaviour_Cover_Tool.java @@ -112,14 +112,22 @@ public class Behaviour_Cover_Tool extends Behaviour_None { ? GT_Utility.determineWrenchingSide(side, hitX, hitY, hitZ) : ForgeDirection.UNKNOWN; if (tSide != ForgeDirection.UNKNOWN) { - mStoredData = tCoverable.getComplexCoverDataAtSide(tSide); - mCoverType = tCoverable.getCoverIDAtSide(tSide); - aList.add("Block Side: " + EnumChatFormatting.AQUA + tSide.name() + EnumChatFormatting.RESET); - aList.add( - "Cover Type: " + EnumChatFormatting.GREEN - + tCoverable.getCoverItemAtSide(tSide) - .getDisplayName() - + EnumChatFormatting.RESET); + if (tCoverable.getCoverBehaviorAtSideNew(tSide) + .allowsCopyPasteTool()) { + mStoredData = tCoverable.getComplexCoverDataAtSide(tSide); + mCoverType = tCoverable.getCoverIDAtSide(tSide); + + aList.add("Block Side: " + EnumChatFormatting.AQUA + tSide.name() + EnumChatFormatting.RESET); + aList.add( + "Cover Type: " + EnumChatFormatting.GREEN + + tCoverable.getCoverItemAtSide(tSide) + .getDisplayName() + + EnumChatFormatting.RESET); + } else { + mStoredData = GregTech_API.sNoBehavior.createDataObject(); + mCoverType = 0; + aList.add("Copy unavailable for this cover type"); + } } else { mStoredData = GregTech_API.sNoBehavior.createDataObject(); mCoverType = 0; |