Guest User

ScrollingOverlay.java

a guest
Oct 17th, 2019
13
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package gigaherz.inventoryspam;
  2.  
  3. import net.minecraft.item.*;
  4. import net.minecraft.entity.player.*;
  5. import net.minecraftforge.common.*;
  6. import com.google.common.collect.*;
  7. import net.minecraft.client.*;
  8. import net.minecraftforge.client.event.*;
  9. import gigaherz.inventoryspam.config.*;
  10. import net.minecraft.client.renderer.*;
  11. import net.minecraft.client.gui.*;
  12. import net.minecraftforge.fml.common.eventhandler.*;
  13. import java.util.function.*;
  14. import net.minecraft.util.text.*;
  15. import net.minecraftforge.fml.common.gameevent.*;
  16. import org.apache.commons.lang3.tuple.*;
  17. import java.util.*;
  18. import net.minecraft.inventory.*;
  19.  
  20. public class ScrollingOverlay extends GuiScreen
  21. {
  22.     private static final int TTL = 240;
  23.     private static final int FADE = 40;
  24.     private int hard_limit;
  25.     private RenderItem renderItem;
  26.     private int dim;
  27.     private int dimLoadTicks;
  28.     private ItemStack[] previous;
  29.     private EntityPlayer playerEntity;
  30.     private ItemStack previousInCursor;
  31.     private final List<ChangeInfo> changeEntries;
  32.    
  33.     public static void init() {
  34.         MinecraftForge.EVENT_BUS.register((Object)new ScrollingOverlay());
  35.     }
  36.    
  37.     private ScrollingOverlay() {
  38.         super();
  39.         this.previousInCursor = ItemStack.EMPTY;
  40.         this.changeEntries = (List<ChangeInfo>)Lists.newArrayList();
  41.         this.renderItem = Minecraft.getMinecraft().getRenderItem();
  42.     }
  43.    
  44.     @SubscribeEvent
  45.     public void renderOverlay(final RenderGameOverlayEvent.Post event) {
  46.         if (!Config.showItemAdditions && !Config.showItemRemovals) {
  47.             return;
  48.         }
  49.         if (event.getType() != RenderGameOverlayEvent.ElementType.CHAT) {
  50.             return;
  51.         }
  52.         final ScaledResolution resolution = event.getResolution();
  53.         int width = resolution.getScaledWidth();
  54.         int height = resolution.getScaledHeight();
  55.         width /= (int)Config.drawScale;
  56.         height /= (int)Config.drawScale;
  57.         final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
  58.         final int iconSize = (int)(16.0 * Config.iconScale);
  59.         final int rightMargin = Config.drawIcon ? (2 + iconSize) : 0;
  60.         final int topMargin1 = 2 + (Config.drawIcon ? Math.max(0, (iconSize - font.FONT_HEIGHT) / 2) : 0);
  61.         final int topMargin2 = 1 + Math.max(0, -(iconSize - font.FONT_HEIGHT) / 2);
  62.         int lineHeight = font.FONT_HEIGHT;
  63.         if (Config.drawIcon) {
  64.             lineHeight = Math.max(2 + iconSize, lineHeight);
  65.         }
  66.         this.hard_limit = height / lineHeight;
  67.         final List<Triple<ChangeInfo, String[], Integer>> computedStrings = (List<Triple<ChangeInfo, String[], Integer>>)Lists.newArrayList();
  68.         int rectWidth;
  69.         final int number;
  70.         synchronized (this.changeEntries) {
  71.             if (this.changeEntries.size() == 0) {
  72.                 return;
  73.             }
  74.             rectWidth = this.computeStrings(computedStrings, font);
  75.             number = computedStrings.size();
  76.             if (number == 0) {
  77.                 return;
  78.             }
  79.         }
  80.         GlStateManager.pushMatrix();
  81.         GlStateManager.scale(Config.drawScale, Config.drawScale, 1.0);
  82.         rectWidth += rightMargin;
  83.         final int rectHeight = lineHeight * number;
  84.         int x = 0;
  85.         int y = 0;
  86.         int align = 0;
  87.         switch (Config.drawPosition) {
  88.             default: {
  89.                 x = width - 2 - rectWidth - Config.drawOffsetHorizontal;
  90.                 y = height - 2 - rectHeight - Config.drawOffsetVertical;
  91.                 align = 1;
  92.                 break;
  93.             }
  94.             case Bottom: {
  95.                 x = (width - rectWidth) / 2 - 2 + Config.drawOffsetHorizontal;
  96.                 y = height - 2 - rectHeight - Config.drawOffsetVertical;
  97.                 align = 0;
  98.                 break;
  99.             }
  100.             case BottomLeft: {
  101.                 x = 2 + Config.drawOffsetHorizontal;
  102.                 y = height - 2 - rectHeight - Config.drawOffsetVertical;
  103.                 align = -1;
  104.                 break;
  105.             }
  106.             case Left: {
  107.                 x = 2 + Config.drawOffsetHorizontal;
  108.                 y = (height - rectHeight) / 2 - 2 + Config.drawOffsetVertical;
  109.                 align = -1;
  110.                 break;
  111.             }
  112.             case TopLeft: {
  113.                 x = 2 + Config.drawOffsetHorizontal;
  114.                 y = 2 + Config.drawOffsetVertical;
  115.                 align = -1;
  116.                 break;
  117.             }
  118.             case Top: {
  119.                 x = (width - rectWidth) / 2 - 2 + Config.drawOffsetHorizontal;
  120.                 y = 2 + Config.drawOffsetVertical;
  121.                 align = 0;
  122.                 break;
  123.             }
  124.             case TopRight: {
  125.                 x = width - 2 - rectWidth - Config.drawOffsetHorizontal;
  126.                 y = 2 + Config.drawOffsetVertical;
  127.                 align = 1;
  128.                 break;
  129.             }
  130.             case Right: {
  131.                 x = width - 2 - rectWidth - Config.drawOffsetHorizontal;
  132.                 y = (height - rectHeight) / 2 - 2 + Config.drawOffsetVertical;
  133.                 align = 1;
  134.                 break;
  135.             }
  136.             case Center: {
  137.                 x = (width - rectWidth) / 2 - 2 + Config.drawOffsetHorizontal;
  138.                 y = (height - rectHeight) / 2 - 2 + Config.drawOffsetVertical;
  139.                 align = 0;
  140.                 break;
  141.             }
  142.         }
  143.         drawRect(x - 2, y - 2, x + rectWidth + 4, y + rectHeight + 4, Integer.MIN_VALUE);
  144.         for (int i = 0; i < computedStrings.size(); ++i) {
  145.             final Triple<ChangeInfo, String[], Integer> e = computedStrings.get(i);
  146.             final ChangeInfo change = e.getLeft();
  147.             final String[] strings = e.getMiddle();
  148.             final int fade = e.getRight();
  149.             int w = 0;
  150.             final int[] widths = new int[strings.length];
  151.             for (int n = 0; n < strings.length; ++n) {
  152.                 final String str = strings[n];
  153.                 final int[] array = widths;
  154.                 final int n3 = n;
  155.                 final int stringWidth = font.getStringWidth(str);
  156.                 array[n3] = stringWidth;
  157.                 final int wn = stringWidth;
  158.                 w += wn;
  159.             }
  160.             final int forcedFade = (Config.fadeLimit > 0) ? (fade * 255 / (Config.fadeLimit + 2)) : 255;
  161.             final int ttlFade = change.ttl * 255 / 40;
  162.             final int alpha = Math.min(255, Math.min(forcedFade, ttlFade));
  163.             final int color = alpha << 24 | ((change.mode == ChangeMode.Obtained) ? 8388479 : 16736095);
  164.             int leftMargin = 0;
  165.             switch (align) {
  166.                 case -1: {
  167.                     leftMargin = 2;
  168.                     break;
  169.                 }
  170.                 case 0: {
  171.                     leftMargin = (rectWidth - w - rightMargin) / 2;
  172.                     break;
  173.                 }
  174.                 case 1: {
  175.                     leftMargin = rectWidth - w - rightMargin;
  176.                     break;
  177.                 }
  178.             }
  179.             GlStateManager.enableBlend();
  180.             int wAcc = 0;
  181.             for (int n2 = 0; n2 < strings.length; ++n2) {
  182.                 font.drawStringWithShadow(strings[n2], (float)(x + leftMargin + wAcc), (float)(y + topMargin1), color);
  183.                 wAcc += widths[n2];
  184.             }
  185.             if (Config.drawIcon) {
  186.                 GlStateManager.pushMatrix();
  187.                 GlStateManager.translate((float)(x + 2 + w + leftMargin), (float)(y + topMargin2), 0.0f);
  188.                 GlStateManager.scale(Config.iconScale, Config.iconScale, 1.0);
  189.                 RenderHelper.enableGUIStandardItemLighting();
  190.                 this.renderItem.renderItemAndEffectIntoGUI(change.item.stack, 0, 0);
  191.                 this.renderItem.renderItemOverlayIntoGUI(font, change.item.stack, 0, 0, (String)null);
  192.                 RenderHelper.disableStandardItemLighting();
  193.                 GlStateManager.popMatrix();
  194.             }
  195.             y += lineHeight;
  196.         }
  197.         GlStateManager.popMatrix();
  198.     }
  199.    
  200.     private int computeStrings(final List<Triple<ChangeInfo, String[], Integer>> computedStrings, final FontRenderer font) {
  201.         int rectWidth = 0;
  202.         final int itemsToShow = Math.min(Math.min(this.hard_limit, Config.softLimit + Config.fadeLimit), this.changeEntries.size());
  203.         final int offset = Math.max(0, this.changeEntries.size() - itemsToShow);
  204.         final int fadeOffset = this.changeEntries.size() - Config.softLimit - Config.fadeLimit;
  205.         for (int i = offset; i < this.changeEntries.size(); ++i) {
  206.             final ChangeInfo change = this.changeEntries.get(i);
  207.             final String[] parts = this.getChangeStrings(change);
  208.             final int w = Arrays.stream(parts).mapToInt(font::func_78256_a).sum();
  209.             rectWidth = Math.max(rectWidth, w);
  210.             computedStrings.add(Triple.of(change, parts, Math.min(Config.fadeLimit + 2, 1 + i - fadeOffset)));
  211.         }
  212.         return rectWidth;
  213.     }
  214.    
  215.     private String[] getChangeStrings(final ChangeInfo change) {
  216.         final String mode = (change.mode == ChangeMode.Obtained) ? "+" : "-";
  217.         final String s1 = String.format("%s%d", mode, change.count);
  218.         if (Config.drawName) {
  219.             final String name = change.item.stack.getDisplayName();
  220.             final String italics = change.item.stack.hasDisplayName() ? ("" + TextFormatting.ITALIC) : "";
  221.             final String s2 = String.format("%s%s", italics, name);
  222.             return new String[] { s1, " ", s2 };
  223.         }
  224.         return new String[] { s1 };
  225.     }
  226.    
  227.     @SubscribeEvent
  228.     public void clientTick(final TickEvent.ClientTickEvent event) {
  229.         if (event.phase != TickEvent.Phase.END) {
  230.             return;
  231.         }
  232.         if (!Config.showItemAdditions && !Config.showItemRemovals) {
  233.             return;
  234.         }
  235.         final EntityPlayer player = (EntityPlayer)Minecraft.getMinecraft().player;
  236.         if (player == null) {
  237.             return;
  238.         }
  239.         if (player != this.playerEntity) {
  240.             if (player.inventoryContainer != null) {
  241.                 player.inventoryContainer = (Container)new ContainerWrapper((ContainerPlayer)player.inventoryContainer, player, () -> {
  242.                     this.previous = null;
  243.                     this.dimLoadTicks = 0;
  244.                     return;
  245.                 });
  246.                 this.playerEntity = player;
  247.             }
  248.             this.previous = null;
  249.         }
  250.         if (player.dimension != this.dim) {
  251.             this.previous = null;
  252.             this.dimLoadTicks = 200;
  253.             this.dim = player.dimension;
  254.         }
  255.         if (this.dimLoadTicks > 0) {
  256.             this.previous = null;
  257.             --this.dimLoadTicks;
  258.             return;
  259.         }
  260.         synchronized (this.changeEntries) {
  261.             this.changeEntries.forEach(e -> --e.ttl);
  262.             while (this.changeEntries.size() > this.hard_limit) {
  263.                 this.changeEntries.remove(0);
  264.             }
  265.             this.changeEntries.removeIf(e -> e.ttl <= 0 || e.count == 0);
  266.         }
  267.         if (this.previous == null || this.previous.length != player.inventory.getSizeInventory()) {
  268.             this.previous = new ItemStack[player.inventory.getSizeInventory()];
  269.             for (int i = 0; i < player.inventory.getSizeInventory(); ++i) {
  270.                 this.previous[i] = safeCopy(player.inventory.getStackInSlot(i));
  271.             }
  272.             this.previousInCursor = player.inventory.getItemStack();
  273.             return;
  274.         }
  275.         final List<Pair<ItemStack, ItemStack>> changes = (List<Pair<ItemStack, ItemStack>>)Lists.newArrayList();
  276.         for (int j = 0; j < player.inventory.getSizeInventory(); ++j) {
  277.             final ItemStack stack = player.inventory.getStackInSlot(j);
  278.             final ItemStack old = this.previous[j];
  279.             if (this.isChangeMeaningful(old, stack)) {
  280.                 changes.add(Pair.of(old, stack));
  281.             }
  282.             this.previous[j] = stack.copy();
  283.         }
  284.         final ItemStack stackInCursor = player.inventory.getItemStack();
  285.         if (this.isChangeMeaningful(stackInCursor, this.previousInCursor)) {
  286.             changes.add(Pair.of(this.previousInCursor, stackInCursor));
  287.         }
  288.         this.previousInCursor = stackInCursor.copy();
  289.         if (changes.size() == 0) {
  290.             return;
  291.         }
  292.         final List<ChangeInfo> changeList = (List<ChangeInfo>)Lists.newArrayList();
  293.         final ItemStack left;
  294.         final boolean leftEmpty;
  295.         final ItemStack right;
  296.         final boolean rightEmpty;
  297.         int difference;
  298.         final List<ChangeInfo> list;
  299.         changes.forEach(change -> {
  300.             left = change.getLeft();
  301.             leftEmpty = (left.getCount() <= 0);
  302.             right = (ItemStack)change.getRight();
  303.             rightEmpty = (right.getCount() <= 0);
  304.             if (areSameishItem(left, right)) {
  305.                 if (!this.isBlacklisted(left)) {
  306.                     difference = right.getCount() - left.getCount();
  307.                     if (difference > 0) {
  308.                         this.obtainedItem(list, left, difference);
  309.                     }
  310.                     else if (difference < 0) {
  311.                         this.lostItem(list, left, -difference);
  312.                     }
  313.                 }
  314.             }
  315.             else {
  316.                 if (!leftEmpty && !this.isBlacklisted(left)) {
  317.                     this.lostItem(list, left, left.getCount());
  318.                 }
  319.                 if (!rightEmpty && !this.isBlacklisted(right)) {
  320.                     this.obtainedItem(list, right, right.getCount());
  321.                 }
  322.             }
  323.             return;
  324.         });
  325.         changeList.removeIf(e -> e.count == 0);
  326.         if (changeList.size() > 0) {
  327.             synchronized (this.changeEntries) {
  328.                 for (final ChangeInfo info : changeList) {
  329.                     if (info.count == 0) {
  330.                         continue;
  331.                     }
  332.                     this.accumulate(this.changeEntries, info.item.stack, info.mode, info.count, false);
  333.                 }
  334.             }
  335.         }
  336.     }
  337.    
  338.     private boolean isBlacklisted(final ItemStack left) {
  339.         return Config.ignoreItems.contains(left.getItem().getRegistryName().toString());
  340.     }
  341.    
  342.     private boolean isChangeMeaningful(final ItemStack a, final ItemStack b) {
  343.         return a.getCount() != b.getCount() || (a != b && (!isStackEmpty(a) || !isStackEmpty(b)) && (a.getItem() != b.getItem() || !Config.ignoreSubitemChanges.contains(a.getItem().getRegistryName().toString())) && !ItemStack.areItemsEqualIgnoreDurability(a, b));
  344.     }
  345.    
  346.     private static boolean areLooselyTheSame(final ItemStack a, final ItemStack b) {
  347.         return a == b || (isStackEmpty(a) && isStackEmpty(b)) || ItemStack.areItemsEqualIgnoreDurability(a, b);
  348.     }
  349.    
  350.     private static boolean areSameishItem(final ItemStack a, final ItemStack b) {
  351.         return a == b || (isStackEmpty(a) && isStackEmpty(b)) || (ItemStack.areItemsEqual(a, b) && ItemStack.areItemStackTagsEqual(a, b));
  352.     }
  353.    
  354.     private static boolean isStackEmpty(final ItemStack stack) {
  355.         return stack.getCount() <= 0;
  356.     }
  357.    
  358.     private static ItemStack safeCopy(final ItemStack stack) {
  359.         return stack.copy();
  360.     }
  361.    
  362.     private void obtainedItem(final List<ChangeInfo> changeList, final ItemStack item, final int added) {
  363.         if (added <= 0 || !Config.showItemAdditions) {
  364.             return;
  365.         }
  366.         this.accumulate(changeList, item, ChangeMode.Obtained, added, true);
  367.     }
  368.    
  369.     private void lostItem(final List<ChangeInfo> changeList, final ItemStack item, final int removed) {
  370.         if (removed <= 0 || !Config.showItemRemovals) {
  371.             return;
  372.         }
  373.         this.accumulate(changeList, item, ChangeMode.Lost, removed, true);
  374.     }
  375.    
  376.     private void accumulate(final List<ChangeInfo> changeList, final ItemStack stack, final ChangeMode mode, int count, final boolean isLocal) {
  377.         if (stack.getCount() <= 0) {
  378.             return;
  379.         }
  380.         final ComparableItem name = new ComparableItem(stack);
  381.         ChangeInfo info = isLocal ? changeList.stream().filter(e -> e.item.equals(name)).findFirst().orElse(null) : changeList.stream().filter(e -> e.item.equals(name) && e.mode == mode).findFirst().orElse(null);
  382.         if (info == null) {
  383.             info = new ChangeInfo(name, mode, count, 240);
  384.             changeList.add(info);
  385.             return;
  386.         }
  387.         if (info.mode != mode) {
  388.             count = -count;
  389.         }
  390.         final ChangeInfo changeInfo = info;
  391.         changeInfo.count += count;
  392.         info.ttl = 240;
  393.         if (info.count < 0) {
  394.             info.count = -info.count;
  395.             info.mode = ((info.mode == ChangeMode.Lost) ? ChangeMode.Obtained : ChangeMode.Lost);
  396.         }
  397.     }
  398.    
  399.     private static /* synthetic */ boolean lambda$accumulate$6(final ComparableItem name, final ChangeMode mode, final ChangeInfo e) {
  400.         return e.item.equals(name) && e.mode == mode;
  401.     }
  402.    
  403.     private static /* synthetic */ boolean lambda$accumulate$5(final ComparableItem name, final ChangeInfo e) {
  404.         return e.item.equals(name);
  405.     }
  406.    
  407.     private static /* synthetic */ boolean lambda$clientTick$4(final ChangeInfo e) {
  408.         return e.count == 0;
  409.     }
  410.    
  411.     private /* synthetic */ void lambda$clientTick$3(final List changeList, final Pair change) {
  412.         final ItemStack left = change.getLeft();
  413.         final boolean leftEmpty = left.getCount() <= 0;
  414.         final ItemStack right = (ItemStack)change.getRight();
  415.         final boolean rightEmpty = right.getCount() <= 0;
  416.         if (areSameishItem(left, right)) {
  417.             if (!this.isBlacklisted(left)) {
  418.                 final int difference = right.getCount() - left.getCount();
  419.                 if (difference > 0) {
  420.                     this.obtainedItem(changeList, left, difference);
  421.                 }
  422.                 else if (difference < 0) {
  423.                     this.lostItem(changeList, left, -difference);
  424.                 }
  425.             }
  426.         }
  427.         else {
  428.             if (!leftEmpty && !this.isBlacklisted(left)) {
  429.                 this.lostItem(changeList, left, left.getCount());
  430.             }
  431.             if (!rightEmpty && !this.isBlacklisted(right)) {
  432.                 this.obtainedItem(changeList, right, right.getCount());
  433.             }
  434.         }
  435.     }
  436.    
  437.     private static /* synthetic */ boolean lambda$clientTick$2(final ChangeInfo e) {
  438.         return e.ttl <= 0 || e.count == 0;
  439.     }
  440.    
  441.     private static /* synthetic */ void lambda$clientTick$1(final ChangeInfo e) {
  442.         --e.ttl;
  443.     }
  444.    
  445.     private /* synthetic */ void lambda$clientTick$0() {
  446.         this.previous = null;
  447.         this.dimLoadTicks = 0;
  448.     }
  449.    
  450.     static /* synthetic */ boolean access$000(final ItemStack x0, final ItemStack x1) {
  451.         return areSameishItem(x0, x1);
  452.     }
  453.    
  454.     private static class ChangeInfo
  455.     {
  456.         final ComparableItem item;
  457.         ChangeMode mode;
  458.         int count;
  459.         int ttl;
  460.        
  461.         ChangeInfo(final ComparableItem item, final ChangeMode mode, final int count, final int ttl) {
  462.             super();
  463.             this.item = item;
  464.             this.mode = mode;
  465.             this.count = count;
  466.             this.ttl = ttl;
  467.         }
  468.     }
  469.    
  470.     private enum ChangeMode
  471.     {
  472.         Obtained,
  473.         Lost;
  474.        
  475.         private static final /* synthetic */ ChangeMode[] $VALUES;
  476.        
  477.         public static ChangeMode[] values() {
  478.             return ChangeMode.$VALUES.clone();
  479.         }
  480.        
  481.         public static ChangeMode valueOf(final String name) {
  482.             return Enum.valueOf(ChangeMode.class, name);
  483.         }
  484.        
  485.         static {
  486.             $VALUES = new ChangeMode[] { ChangeMode.Obtained, ChangeMode.Lost };
  487.         }
  488.     }
  489.    
  490.     private static class ComparableItem
  491.     {
  492.         ItemStack stack;
  493.        
  494.         ComparableItem(final ItemStack stack) {
  495.             super();
  496.             (this.stack = stack.copy()).setCount(1);
  497.         }
  498.        
  499.         @Override
  500.         public boolean equals(final Object obj) {
  501.             if (!(obj instanceof ComparableItem)) {
  502.                 return false;
  503.             }
  504.             final ItemStack stack = ((ComparableItem)obj).stack;
  505.             return areSameishItem(stack, this.stack);
  506.         }
  507.        
  508.         @Override
  509.         public int hashCode() {
  510.             return this.stack.getItem().hashCode() * 31 ^ this.stack.getMetadata();
  511.         }
  512.     }
  513. }
RAW Paste Data