SHARE
TWEET

Untitled

a guest May 25th, 2019 8 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.pau101.cacti;
  2.  
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.Collection;
  6. import java.util.Collections;
  7. import java.util.HashMap;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.Locale;
  11. import java.util.Map;
  12.  
  13. import net.minecraft.client.Minecraft;
  14. import net.minecraft.client.gui.FontRenderer;
  15. import net.minecraft.client.gui.GuiButton;
  16. import net.minecraft.client.gui.inventory.GuiContainer;
  17. import net.minecraft.client.gui.inventory.GuiContainerCreative;
  18. import net.minecraft.client.renderer.GlStateManager;
  19. import net.minecraft.client.renderer.InventoryEffectRenderer;
  20. import net.minecraft.client.resources.I18n;
  21. import net.minecraft.client.resources.IResource;
  22. import net.minecraft.client.resources.SimpleResource;
  23. import net.minecraft.creativetab.CreativeTabs;
  24. import net.minecraft.potion.Potion;
  25. import net.minecraft.potion.PotionEffect;
  26. import net.minecraft.util.ResourceLocation;
  27. import net.minecraftforge.client.event.GuiScreenEvent.PotionShiftEvent;
  28. import net.minecraftforge.common.ForgeModContainer;
  29. import net.minecraftforge.common.MinecraftForge;
  30. import net.minecraftforge.fml.client.event.ConfigChangedEvent;
  31. import net.minecraftforge.fml.common.Loader;
  32. import net.minecraftforge.fml.common.Mod;
  33. import net.minecraftforge.fml.common.Mod.EventHandler;
  34. import net.minecraftforge.fml.common.ModContainer;
  35. import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
  36. import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
  37. import net.minecraftforge.fml.relauncher.ReflectionHelper;
  38.  
  39. import com.google.common.collect.ImmutableList;
  40. import com.google.common.collect.Ordering;
  41. import com.pau101.cacti.api.CactiAPI;
  42. import com.pau101.cacti.api.CactiEntry;
  43. import com.pau101.cacti.api.CactiEntryCategory;
  44. import com.pau101.cacti.api.CactiEntryTabGroup;
  45. import com.pau101.cacti.config.Configurator;
  46. import com.pau101.cacti.config.DisplaySide;
  47.  
  48. @Mod(
  49.     modid = Cacti.MODID,
  50.     name = Cacti.NAME,
  51.     version = Cacti.VERSION,
  52.     clientSideOnly = true,
  53.     guiFactory = "com.pau101.cacti.gui.CactiGuiFactory"
  54. )
  55. public class Cacti {
  56.     public static final String MODID = "cacti";
  57.  
  58.     public static final String NAME = "Cacti";
  59.  
  60.     public static final String VERSION = "1.0.1";
  61.  
  62.     private static final ResourceLocation WIDGETS_TEX = new ResourceLocation(MODID, "textures/widgets.png");
  63.  
  64.     private static final ResourceLocation TABS_TEX = new ResourceLocation("textures/gui/container/creative_inventory/tabs.png");
  65.  
  66.     private static final ResourceLocation BUTTON_TEX = new ResourceLocation("textures/gui/widgets.png");
  67.  
  68.     private static final String MINECRAFT_TAB_GROUP = "minecraft";
  69.  
  70.     private static final String MISC_TAB_GROUP = "misc";
  71.  
  72.     private static final String MODS_TAB_GROUP = "mods";
  73.  
  74.     private static final int ENTRIES_PER_PAGE = 8;
  75.  
  76.     private static final int RIBBON_TILE_SIZE = 17;
  77.  
  78.     private static final int RIBBON_HEIGHT = 16;
  79.  
  80.     private static final int RIBBON_START_Y_OFFSET = 3;
  81.  
  82.     private static final int RIBBON_X_OFFSET = 17;
  83.  
  84.     private static final int MAX_NAME_WIDTH = 109;
  85.  
  86.     private static final int BUTTON_ID_PARENT_CATEGORY = 0x534D57;
  87.  
  88.     private static final int BUTTON_ID_PAGE_PREVIOUS = 0xC6E9A5EE;
  89.  
  90.     private static final int BUTTON_ID_PAGE_NEXT = 0x8F087F60;
  91.  
  92.     private static final int LEFT_BUTTON_WIDTH = 106;
  93.  
  94.     private static boolean shouldUseButtonRibbonRender;
  95.  
  96.     private static Map<ModContainer, List<CreativeTabs>> capturedCreativeTabs = new HashMap<>();
  97.  
  98.     private static Map<ModContainer, List<CreativeTabs>> creativeTabs = new HashMap<>();
  99.  
  100.     private static CactiEntryCategory currentCategory = CactiAPI.categories();
  101.  
  102.     private static CactiEntryTabGroup currentTabGroup;
  103.  
  104.     private static int categoryPage;
  105.  
  106.     private static int[] ribbonWidths = new int[ENTRIES_PER_PAGE];
  107.  
  108.     private static List<CactiEntry> currentPageEntries;
  109.  
  110.     private static int entryCount;
  111.  
  112.     private static GuiButton parentCategory;
  113.  
  114.     private static GuiButton pagePrevious;
  115.  
  116.     private static GuiButton pageNext;
  117.  
  118.     @EventHandler
  119.     public void init(FMLPreInitializationEvent event) {
  120.         MinecraftForge.EVENT_BUS.register(this);
  121.         Configurator.init(event);
  122.     }
  123.  
  124.     @SubscribeEvent
  125.     public void onPotionShift(PotionShiftEvent event) {
  126.         if (Minecraft.getMinecraft().currentScreen instanceof GuiContainerCreative) {
  127.             event.setCanceled(true);
  128.         }
  129.     }
  130.  
  131.     @SubscribeEvent
  132.     public void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) {
  133.         if (Cacti.MODID.equals(event.getModID())) {
  134.             Configurator.update();
  135.         }
  136.     }
  137.  
  138.     @HookInvoked(callerClass = CreativeTabs.class, callerMethods = "<init>(ILjava/lang/String;)V")
  139.     public static void initCreativeTab(CreativeTabs tab) {
  140.         ModContainer mod = null;
  141.         String name = tab.getClass().getName();
  142.         int pkgIdx = name.lastIndexOf('.');
  143.         if (pkgIdx > -1) {
  144.             String pkg = name.substring(0, pkgIdx);
  145.             List<ModContainer> owners = new ArrayList<>();
  146.             for (ModContainer container : Loader.instance().getModList()) {
  147.                 if (container.getOwnedPackages().contains(pkg)) {
  148.                     owners.add(container);
  149.                 }
  150.             }
  151.             if (owners.size() == 1) {
  152.                 mod = owners.get(0);
  153.             } else if (owners.size() > 1) {
  154.                 String[] unfavorable = { "api", "lib", "util" };
  155.                 owners.sort((m1, m2) -> {
  156.                     String name1 = m1.getName().toLowerCase(Locale.ROOT);
  157.                     String name2 = m2.getName().toLowerCase(Locale.ROOT);
  158.                     for (String k : unfavorable) {
  159.                         if (name1.contains(k)) {
  160.                             return 1;
  161.                         }
  162.                         if (name2.contains(k)) {
  163.                             return -1;
  164.                         }
  165.                     }
  166.                     return 0;
  167.                 });
  168.                 mod = owners.get(0);
  169.             }
  170.         }
  171.         if (mod == null) {
  172.             mod = Loader.instance().activeModContainer();
  173.         }
  174.         List<CreativeTabs> tabs = capturedCreativeTabs.get(mod);
  175.         if (tabs == null) {
  176.             tabs = new ArrayList<CreativeTabs>();
  177.             capturedCreativeTabs.put(mod, tabs);
  178.         }
  179.         tabs.add(tab);
  180.     }
  181.  
  182.     private static void initializeCapturedCreativeTabs() {
  183.         Iterator<ModContainer> mods = capturedCreativeTabs.keySet().iterator();
  184.         while (mods.hasNext()) {
  185.             ModContainer mod = mods.next();
  186.             List<CreativeTabs> tabs = capturedCreativeTabs.get(mod);
  187.             mods.remove();
  188.             List<CreativeTabs> existingTabs = creativeTabs.get(mod);
  189.             if (existingTabs == null) {
  190.                 existingTabs = new ArrayList<CreativeTabs>();
  191.                 creativeTabs.put(mod, existingTabs);
  192.             }
  193.             existingTabs.addAll(tabs);
  194.             boolean addToGroupedMods = tabs.size() == 1 && Configurator.groupSingleTabMods();
  195.             for (CreativeTabs tab : tabs) {
  196.                 if (CactiAPI.categories().contains(tab)) {
  197.                     continue;
  198.                 }
  199.                 CactiEntryTabGroup tabGroup;
  200.                 boolean isMod = mod != null;
  201.                 String id = isMod ? mod.getModId() : MINECRAFT_TAB_GROUP;
  202.                 if (CactiAPI.categories().hasCategory(id)) {
  203.                     CactiEntryCategory category = CactiAPI.categories().getCategory(id);
  204.                     tabGroup = category.getTabGroup(MISC_TAB_GROUP);
  205.                     if (tabGroup == null) {
  206.                         tabGroup = category.withTabGroup(MISC_TAB_GROUP);
  207.                         tabGroup.setUnlocalizedNameKey("itemGroup.misc");
  208.                     }
  209.                 } else {
  210.                     String groupId = addToGroupedMods ? MODS_TAB_GROUP : id;
  211.                     tabGroup = CactiAPI.categories().getTabGroup(groupId);
  212.                     if (tabGroup == null) {
  213.                         tabGroup = CactiAPI.categories().withTabGroup(groupId);
  214.                         if (isMod && !addToGroupedMods) {
  215.                             tabGroup.setCustomName(mod.getName());
  216.                         }
  217.                     }
  218.                 }
  219.                 tabGroup.withTab(tab);
  220.             }
  221.         }
  222.         sortRootEntries();
  223.     }
  224.  
  225.     public static void ungroupSingleTabMods() {
  226.         boolean checkAdjustTab = currentTabGroup != null && currentTabGroup.getId().equals(MODS_TAB_GROUP);
  227.         String modid = null;
  228.         if (CactiAPI.categories().hasTabGroup(MODS_TAB_GROUP)) {
  229.             CactiAPI.categories().removeEntry(MODS_TAB_GROUP);
  230.             Iterator<ModContainer> mods = creativeTabs.keySet().iterator();
  231.             while (mods.hasNext()) {
  232.                 ModContainer mod = mods.next();
  233.                 List<CreativeTabs> tabs = creativeTabs.get(mod);
  234.                 if (tabs.size() == 1) {
  235.                     CreativeTabs tab = tabs.get(0);
  236.                     CactiAPI.categories().removeEntry(mod.getModId());
  237.                     CactiEntryTabGroup modTab = CactiAPI.categories()
  238.                         .withTabGroup(mod.getModId())
  239.                         .withTab(tab);
  240.                     modTab.setCustomName(mod.getName());
  241.                     if (checkAdjustTab && tab.getTabIndex() == GuiContainerCreative.selectedTabIndex) {
  242.                         currentTabGroup = modTab;
  243.                         currentCategory = CactiAPI.categories();
  244.                         GuiContainerCreative.selectedTabIndex = 0;
  245.                         checkAdjustTab = false;
  246.                     }
  247.                 }
  248.             }
  249.         }
  250.         sortRootEntries();
  251.         reinitialize();
  252.     }
  253.  
  254.     public static void groupSingleTabMods() {
  255.         boolean checkAdjustTab = true;
  256.         Iterator<ModContainer> mods = creativeTabs.keySet().iterator();
  257.         while (mods.hasNext()) {
  258.             ModContainer mod = mods.next();
  259.             List<CreativeTabs> tabs = creativeTabs.get(mod);
  260.             if (tabs.size() == 1) {
  261.                 CactiAPI.categories().removeEntry(mod.getModId());
  262.                 CactiEntryTabGroup groupedMods = CactiAPI.categories().getTabGroup(MODS_TAB_GROUP);
  263.                 if (groupedMods == null) {
  264.                     groupedMods = CactiAPI.categories().withTabGroup(MODS_TAB_GROUP);
  265.                 }
  266.                 if (checkAdjustTab && currentTabGroup.getId().equals(mod.getModId())) {
  267.                     currentTabGroup = groupedMods;
  268.                     currentCategory = CactiAPI.categories();
  269.                     int tabId = groupedMods.size();
  270.                     // skip over search
  271.                     if (groupedMods.size() > 4) {
  272.                         tabId++;
  273.                     }
  274.                     // skip over inventory
  275.                     if (groupedMods.size() > 10) {
  276.                         tabId++;
  277.                     }
  278.                     GuiContainerCreative.selectedTabIndex = tabId;
  279.                     checkAdjustTab = false;
  280.                 }
  281.                 groupedMods.withTab(tabs.get(0));
  282.             }
  283.         }
  284.         sortRootEntries();
  285.         reinitialize();
  286.     }
  287.  
  288.     private static void sortRootEntries() {
  289.         List<CactiEntry> entries = new ArrayList<>(CactiAPI.categories().getEntries());
  290.         CactiEntry minecraft = CactiAPI.categories().get(MINECRAFT_TAB_GROUP);
  291.         CactiEntry groupedMods = CactiAPI.categories().get(MODS_TAB_GROUP);
  292.         entries.remove(minecraft);
  293.         if (groupedMods != null) {
  294.             entries.remove(groupedMods);
  295.         }
  296.         Collections.sort(entries);
  297.         entries.add(0, minecraft);
  298.         if (groupedMods != null) {
  299.             entries.add(1, groupedMods);
  300.         }
  301.         CactiAPI.categories().clear();
  302.         for (CactiEntry entry : entries) {
  303.             CactiAPI.categories().addEntry(entry);
  304.         }
  305.     }
  306.  
  307.     private static void reinitialize() {
  308.         categoryPage = currentCategory.getEntries().indexOf(currentTabGroup) / ENTRIES_PER_PAGE;
  309.         if (Minecraft.getMinecraft().currentScreen instanceof GuiContainerCreative) {
  310.             initCurrent((GuiContainerCreative) Minecraft.getMinecraft().currentScreen);
  311.         }
  312.     }
  313.  
  314.     @HookInvoked(callerClass = GuiContainerCreative.class, callerMethods = "initGui()V")
  315.     public static void initGui(GuiContainerCreative gui) {
  316.         int parentCategoryX, pagePreviousX, pageNextX;
  317.         if (Configurator.displaySide() == DisplaySide.LEFT) {
  318.             int left = gui.getGuiLeft() - 5;
  319.             pagePreviousX = parentCategoryX = left - LEFT_BUTTON_WIDTH;
  320.             pageNextX = left - 20;
  321.         } else {
  322.             int right = gui.getGuiLeft() + gui.getXSize() + 5;
  323.             pagePreviousX = parentCategoryX = right;
  324.             pageNextX = right + LEFT_BUTTON_WIDTH - 20;
  325.         }
  326.         parentCategory = new GuiButton(BUTTON_ID_PARENT_CATEGORY, parentCategoryX, gui.getGuiTop() - 22, LEFT_BUTTON_WIDTH, 20, "");
  327.         pagePrevious = new GuiButton(BUTTON_ID_PAGE_PREVIOUS, pagePreviousX, gui.getGuiTop() + gui.getYSize() + 1, 20, 20, "<");
  328.         pageNext = new GuiButton(BUTTON_ID_PAGE_NEXT, pageNextX, gui.getGuiTop() + gui.getYSize() + 1, 20, 20, ">");
  329.         gui.buttonList.add(parentCategory);
  330.         gui.buttonList.add(pagePrevious);
  331.         gui.buttonList.add(pageNext);
  332.         initializeCapturedCreativeTabs();
  333.         if (!Configurator.rememberLastTab()) {
  334.             GuiContainerCreative.selectedTabIndex = 0;
  335.             currentCategory = CactiAPI.categories();
  336.             currentTabGroup = null;
  337.             categoryPage = 0;
  338.         }
  339.         initCurrent(gui);
  340.         String widgetsOwner = getCurrentResourceOwner(WIDGETS_TEX);
  341.         String tabsOwner = getCurrentResourceOwner(TABS_TEX);
  342.         String widgetsOwnerName = getName(widgetsOwner);
  343.         String tabsOwnerName = getName(tabsOwner);
  344.         String defaultPack = Minecraft.getMinecraft().mcDefaultResourcePack.getPackName();
  345.         String devDefaultPack = ForgeModContainer.getInstance().getName();
  346.         if (widgetsOwner.isEmpty() || tabsOwner.isEmpty()) {
  347.             shouldUseButtonRibbonRender = true;
  348.         } else if (widgetsOwnerName.equals(Cacti.NAME) && (tabsOwnerName.equals(defaultPack) || tabsOwnerName.equals(devDefaultPack))) {
  349.             shouldUseButtonRibbonRender = false;
  350.         } else {
  351.             shouldUseButtonRibbonRender = !widgetsOwner.equals(tabsOwner);
  352.         }
  353.     }
  354.  
  355.     private static void initCurrent(GuiContainerCreative gui) {
  356.         int index = GuiContainerCreative.selectedTabIndex;
  357.         GuiContainerCreative.selectedTabIndex = -1;
  358.         CactiEntryTabGroup group = currentTabGroup;
  359.         setCurrentCategory(gui, currentCategory, categoryPage);
  360.         if (group != null) {
  361.             setCurrentTabGroup(gui, group);
  362.         }
  363.         if (index >= 0 && index < CreativeTabs.CREATIVE_TAB_ARRAY.length) {
  364.             CreativeTabs tab = CreativeTabs.CREATIVE_TAB_ARRAY[index];
  365.             if (tab != null) {
  366.                 gui.setCurrentCreativeTab(tab);
  367.                 setTabPage((index - 2) / 10);
  368.             }
  369.         }
  370.     }
  371.  
  372.     private static String getCurrentResourceOwner(ResourceLocation location) {
  373.         try {
  374.             IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location);
  375.             if (res instanceof SimpleResource) {
  376.                 return ((SimpleResource) res).getResourcePackName();
  377.             }
  378.         } catch (IOException e) {}
  379.         return "";
  380.     }
  381.  
  382.     private static String getName(String str) {
  383.         return str.substring(str.indexOf(':') + 1);
  384.     }
  385.  
  386.     private static void setCurrentEntry(GuiContainerCreative gui, CactiEntry entry) {
  387.         if (entry instanceof CactiEntryCategory) {
  388.             setCurrentCategory(gui, (CactiEntryCategory) entry, 0);
  389.         } else if (entry instanceof CactiEntryTabGroup) {
  390.             setCurrentTabGroup(gui, (CactiEntryTabGroup) entry);
  391.         }
  392.     }
  393.  
  394.     private static void setCurrentCategory(GuiContainerCreative gui, CactiEntryCategory category, int page) {
  395.         currentCategory = category;
  396.         categoryPage = page;
  397.         ImmutableList<CactiEntry> entries = category.getEntries();
  398.         entryCount = entries.size();
  399.         updatePageEntries(gui);
  400.         updatePageButtons(gui);
  401.         updateParentCategoryButton(gui);
  402.     }
  403.  
  404.     private static void setCurrentTabGroup(GuiContainerCreative gui, CactiEntryTabGroup group) {
  405.         currentTabGroup = group;
  406.         if (group == null) {
  407.             updateTabs(gui, ImmutableList.<CreativeTabs>of());
  408.         } else {
  409.             updateTabs(gui, group.getTabs());
  410.         }
  411.     }
  412.  
  413.     private static void updateTabs(GuiContainerCreative gui, ImmutableList<CreativeTabs> tabs) {
  414.         CreativeTabs[] tabsArray = new CreativeTabs[tabs.size()];
  415.         int len = 0;
  416.         for (CreativeTabs tab : tabs) {
  417.             if (tab == CreativeTabs.INVENTORY || tab == CreativeTabs.SEARCH) {
  418.                 continue;
  419.             }
  420.             tabsArray[len++] = tab;
  421.         }
  422.         CreativeTabs[] arr = CreativeTabs.CREATIVE_TAB_ARRAY = new CreativeTabs[Math.max(len + 2, 12)];
  423.         arr[CreativeTabs.SEARCH.getTabIndex()] = CreativeTabs.SEARCH;
  424.         arr[CreativeTabs.INVENTORY.getTabIndex()] = CreativeTabs.INVENTORY;
  425.         for (int i = 0, idx = 0; i < len; idx++) {
  426.             if (arr[idx] == null) {
  427.                 (arr[idx] = tabsArray[i++]).tabIndex = idx;
  428.             }
  429.         }
  430.         int maxPages;
  431.         final int prevId = 101, nextId = 102;
  432.         if (arr.length > 12) {
  433.             boolean needPrev = true, needNext = true;
  434.             for (GuiButton button : gui.buttonList) {
  435.                 if (button.id == prevId) {
  436.                     needPrev = false;
  437.                 } else if (button.id == nextId) {
  438.                     needNext = false;
  439.                 }
  440.             }
  441.             if (needPrev) {
  442.                 gui.buttonList.add(new GuiButton(prevId, gui.getGuiLeft(), gui.getGuiTop() - 50, 20, 20, "<"));
  443.             }
  444.             if (needNext) {
  445.                 gui.buttonList.add(new GuiButton(nextId, gui.getGuiLeft() + gui.getXSize() - 20, gui.getGuiTop() - 50, 20, 20, ">"));
  446.             }
  447.             maxPages = (arr.length - 3) / 10;
  448.         } else {
  449.             Iterator<GuiButton> buttonIter = gui.buttonList.iterator();
  450.             while (buttonIter.hasNext()) {
  451.                 GuiButton button = buttonIter.next();
  452.                 if (button.id == prevId || button.id == nextId) {
  453.                     buttonIter.remove();
  454.                 }
  455.             }
  456.             maxPages = 0;
  457.         }
  458.         // Can't AT a Forge patched member
  459.         ReflectionHelper.setPrivateValue(GuiContainerCreative.class, gui, maxPages, "maxPages");
  460.         setTabPage(0);
  461.         if (tabs.isEmpty()) {
  462.             gui.setCurrentCreativeTab(CreativeTabs.INVENTORY);
  463.         } else {
  464.             gui.setCurrentCreativeTab(tabs.get(0));
  465.         }
  466.     }
  467.  
  468.     private static void setTabPage(int tabPage) {
  469.         ReflectionHelper.setPrivateValue(GuiContainerCreative.class, null, tabPage, "tabPage");
  470.     }
  471.  
  472.     private static void updatePageEntries(GuiContainerCreative gui) {
  473.         ImmutableList<CactiEntry> entries = currentCategory.getEntries();
  474.         // Hide the Minecraft entry if there are no other entries
  475.         if (currentCategory == CactiAPI.categories() && entries.size() == 1) {
  476.             currentPageEntries = Collections.EMPTY_LIST;
  477.         } else {
  478.             int start = categoryPage * ENTRIES_PER_PAGE;
  479.             int end = Math.min(entries.size(), (categoryPage + 1) * ENTRIES_PER_PAGE);
  480.             currentPageEntries = entries = entries.subList(start, end);
  481.         }
  482.         initTabGroup(gui, entries);
  483.         updateRibbonWidths();
  484.     }
  485.  
  486.     private static void initTabGroup(GuiContainerCreative gui, List<CactiEntry> entries) {
  487.         CactiEntryTabGroup group = null;
  488.         if (entries.size() > 0) {
  489.             CactiEntry entry = entries.get(0);
  490.             if (entry instanceof CactiEntryTabGroup) {
  491.                 group = (CactiEntryTabGroup) entry;
  492.             }
  493.         }
  494.         setCurrentTabGroup(gui, group);
  495.     }
  496.  
  497.     private static void updateRibbonWidths() {
  498.         FontRenderer font = Minecraft.getMinecraft().fontRenderer;
  499.         for (int i = 0; i < ribbonWidths.length; i++) {
  500.             if (i < currentPageEntries.size()) {
  501.                 ribbonWidths[i] = font.getStringWidth(currentPageEntries.get(i).getDisplayName());
  502.             } else {
  503.                 ribbonWidths[i] = 0;
  504.             }
  505.         }
  506.     }
  507.  
  508.     private static void updatePageButtons(GuiContainerCreative gui) {
  509.         pagePrevious.visible = pageNext.visible = entryCount > ENTRIES_PER_PAGE;
  510.         updatePageButtonEnabledStates(gui);
  511.     }
  512.  
  513.     private static void updateParentCategoryButton(GuiContainerCreative gui) {
  514.         CactiEntryCategory owner = currentCategory.getOwner();
  515.         if (parentCategory.visible = owner != null) {
  516.             String name = owner.getDisplayName();
  517.             parentCategory.displayString = name;
  518.         }
  519.     }
  520.  
  521.     private static void updatePageButtonEnabledStates(GuiContainerCreative gui) {
  522.         pagePrevious.enabled = categoryPage > 0;
  523.         pageNext.enabled = categoryPage < (entryCount - 1) / ENTRIES_PER_PAGE;
  524.     }
  525.  
  526.     @HookInvoked(callerClass = GuiContainerCreative.class, callerMethods = "mouseReleased(III)V")
  527.     public static void mouseReleased(GuiContainerCreative gui, int mouseX, int mouseY, int state) {
  528.         if (state == 0) {
  529.             CactiEntry entry = getCategoryAtCursor(gui, mouseX, mouseY);
  530.             if (entry != null) {
  531.                 setCurrentEntry(gui, entry);
  532.             }
  533.         }
  534.     }
  535.  
  536.     @HookInvoked(callerClass = GuiContainerCreative.class, callerMethods = "actionPerformed(Lnet/minecraft/client/gui/GuiButton;)V")
  537.     public static void actionPerformed(GuiContainerCreative gui, int id) {
  538.         switch (id) {
  539.             case BUTTON_ID_PAGE_PREVIOUS:
  540.                 categoryPage -= 2;
  541.             case BUTTON_ID_PAGE_NEXT:
  542.                 categoryPage++;
  543.                 updatePageButtonEnabledStates(gui);
  544.                 updatePageEntries(gui);
  545.                 break;
  546.             case BUTTON_ID_PARENT_CATEGORY:
  547.                 setCurrentCategory(gui, currentCategory.getOwner(), 0);
  548.         }
  549.     }
  550.  
  551.     private static CactiEntry getCategoryAtCursor(GuiContainerCreative gui, int mouseX, int mouseY) {
  552.         int xLeft, xRight, xAlong;
  553.         if (Configurator.displaySide() == DisplaySide.LEFT) {
  554.             xLeft = 0;
  555.             xRight = gui.getGuiLeft();
  556.             xAlong = gui.getGuiLeft() - mouseX - 1;
  557.         } else {
  558.             xLeft = gui.getGuiLeft() + gui.getXSize();
  559.             xRight = gui.width;
  560.             xAlong = mouseX - xLeft;
  561.         }
  562.         if (mouseX >= xLeft && mouseX < xRight && mouseY >= gui.getGuiTop() + RIBBON_START_Y_OFFSET) {
  563.             int index = (mouseY - gui.getGuiTop() - RIBBON_START_Y_OFFSET - 1) / (RIBBON_TILE_SIZE - 1);
  564.             if (index < currentPageEntries.size() && xAlong < ribbonWidths[index] + 6) {
  565.                 return currentPageEntries.get(index);
  566.             }
  567.         }
  568.         return null;
  569.     }
  570.  
  571.     private enum Pass {
  572.         BACKGROUND, TEXT;
  573.     }
  574.  
  575.     @HookInvoked(callerClass = GuiContainerCreative.class, callerMethods = "drawGuiContainerBackgroundLayer(FII)V")
  576.     public static void drawBackground(GuiContainerCreative gui, float delta, int mouseX, int mouseY) {
  577.         if (currentPageEntries.size() == 0) {
  578.             return;
  579.         }
  580.         GlStateManager.disableLighting();
  581.         gui.mc.getTextureManager().bindTexture(shouldUseButtonRibbonRender ? BUTTON_TEX : WIDGETS_TEX);
  582.         renderEntryRibbonTiles(gui, currentPageEntries, currentTabGroup, Pass.BACKGROUND);
  583.         renderEntryRibbonTiles(gui, currentPageEntries, currentTabGroup, Pass.TEXT);
  584.         int pages = (entryCount - 1) / ENTRIES_PER_PAGE;
  585.         boolean parentCategoryButtonVisible = parentCategory.visible;
  586.         boolean renderPages = pages > 0;
  587.         if (parentCategoryButtonVisible || renderPages) {
  588.             int leftX = gui.getGuiLeft() - 5;
  589.             int shift = Math.max(0, LEFT_BUTTON_WIDTH - leftX + 2);
  590.             int leftWidth = LEFT_BUTTON_WIDTH - shift;
  591.             leftX += shift;
  592.             if (parentCategoryButtonVisible) {
  593.                 parentCategory.width = leftWidth;
  594.                 if (Configurator.displaySide() == DisplaySide.LEFT) {
  595.                     parentCategory.x = leftX - LEFT_BUTTON_WIDTH;
  596.                 }
  597.                 parentCategory.displayString = fitString(gui.mc.fontRenderer, currentCategory.getDisplayName(), parentCategory.width - 6);
  598.             }
  599.             if (renderPages) {
  600.                 if (Configurator.displaySide() == DisplaySide.LEFT) {
  601.                     pagePrevious.x = leftX - LEFT_BUTTON_WIDTH;
  602.                 } else {
  603.                     pageNext.x = parentCategory.x + leftWidth - pageNext.width;
  604.                 }
  605.                 FontRenderer font = gui.mc.fontRenderer;
  606.                 String str = String.format("%d / %d", categoryPage + 1, pages + 1);
  607.                 if (pageNext.x - pagePrevious.x - pagePrevious.width - 5 < font.getStringWidth(str)) {
  608.                     str = Integer.toString(categoryPage + 1);
  609.                 }
  610.                 int w = font.getStringWidth(str);
  611.                 font.drawString(str, (pagePrevious.x + pagePrevious.width + pageNext.x) / 2 - w / 2, gui.getGuiTop() + gui.getYSize() + 7, 0xFFFFFF);
  612.             }
  613.         }
  614.     }
  615.  
  616.     @HookInvoked(callerClass = GuiContainerCreative.class, callerMethods = "drawScreen(IIF)V")
  617.     public static void drawScreen(GuiContainerCreative gui, int mouseX, int mouseY) {
  618.         CactiEntry entry = getCategoryAtCursor(gui, mouseX, mouseY);
  619.         if (entry != null) {
  620.             FontRenderer font = gui.mc.fontRenderer;
  621.             String name = entry.getDisplayName();
  622.             String shown = fitString(font, name, getAvailableEntryWidth(font, gui.getGuiLeft() - 3, name) - 4);
  623.             if (!name.equals(shown)) {
  624.                 gui.drawHoveringText(entry.getDisplayName(), mouseX, mouseY);
  625.             }
  626.         }
  627.         GlStateManager.disableLighting();
  628.     }
  629.  
  630.     private static void renderEntryRibbonTiles(GuiContainer gui, List<CactiEntry> entries, CactiEntry selected, Pass pass) {
  631.         FontRenderer font = gui.mc.fontRenderer;
  632.         int rightSpace = gui.getGuiLeft() - 3;
  633.         for (int i = 0, size = entries.size(); i < size; i++) {
  634.             CactiEntry entry = entries.get(i);
  635.             String name = entry.getDisplayName();
  636.             int width = getAvailableEntryWidth(font, rightSpace, name);
  637.             name = fitString(font, name, width - 4);
  638.             // ceil tiles
  639.             int tiles = (width - RIBBON_TILE_SIZE + (RIBBON_TILE_SIZE + 1)) / RIBBON_TILE_SIZE;
  640.             int offset = (width + 1) % RIBBON_TILE_SIZE;
  641.             int x;
  642.             if (Configurator.displaySide() == DisplaySide.LEFT) {
  643.                 x = gui.getGuiLeft() - RIBBON_TILE_SIZE - offset + RIBBON_X_OFFSET;
  644.             } else {
  645.                 x = gui.getGuiLeft() + gui.getXSize() - RIBBON_TILE_SIZE * 2 + offset + RIBBON_X_OFFSET;
  646.             }
  647.             int y = gui.getGuiTop() + RIBBON_START_Y_OFFSET + RIBBON_HEIGHT * i;
  648.             boolean isSelected = entry == selected;
  649.             if (shouldUseButtonRibbonRender) {
  650.                 renderButtonRibbon(gui, isSelected, pass, font, name, width, x, y);
  651.             } else {
  652.                 renderRegularRibbon(gui, isSelected, pass, font, name, width, tiles, offset, x, y);
  653.             }
  654.         }
  655.     }
  656.  
  657.     private static int getAvailableEntryWidth(FontRenderer font, int rightSpace, String name) {
  658.         int width = font.getStringWidth(name) + 5;
  659.         return Math.max(10, width - Math.max(0, width - rightSpace));
  660.     }
  661.  
  662.     private static void renderButtonRibbon(GuiContainer gui, boolean isSelected, Pass pass, FontRenderer font, String name, int width, int x, int y) {
  663.         width -= 1;
  664.         if (pass == Pass.TEXT) {
  665.             if (Configurator.displaySide() == DisplaySide.LEFT) {
  666.                 font.drawStringWithShadow(name, gui.getGuiLeft() - width - (width + 1) % 2, y + 3, 0xFFFFFF);
  667.             } else {
  668.                 font.drawStringWithShadow(name, gui.getGuiLeft() + gui.getXSize() + 5, y + 3, 0xFFFFFF);
  669.             }
  670.             return;
  671.         }
  672.         if (Configurator.displaySide() == DisplaySide.LEFT) {
  673.             x = gui.getGuiLeft() - width - 4 + width % 2;
  674.         } else {
  675.             x = gui.getGuiLeft() + gui.getXSize() + 2;
  676.         }
  677.         int vOffset = isSelected ? 20 : 0;
  678.         width = width / 2 + 1;
  679.         gui.drawTexturedModalRect(x, y, 0, 46 + vOffset, width, 8);
  680.         gui.drawTexturedModalRect(x, y + 8, 0, 46 + vOffset + 13, width, 7);
  681.         gui.drawTexturedModalRect(x + width, y, 200 - width, 46 + vOffset, width, 8);
  682.         gui.drawTexturedModalRect(x + width, y + 8, 200 - width, 46 + vOffset + 13, width, 7);
  683.     }
  684.  
  685.     private static void renderRegularRibbon(GuiContainer gui, boolean isSelected, Pass pass, FontRenderer font, String name, int width, int tiles, int offset, int x, int y) {
  686.         if (pass == Pass.TEXT) {
  687.             if (Configurator.displaySide() == DisplaySide.LEFT) {
  688.                 font.drawString(name, gui.getGuiLeft() - width + 4, y + 5, 0x404040);
  689.             } else {
  690.                 font.drawString(name, gui.getGuiLeft() + gui.getXSize() + 2, y + 5, 0x404040);
  691.             }
  692.             return;
  693.         }
  694.         int v;
  695.         if (isSelected) {
  696.             v = 0;
  697.             GlStateManager.translate(0, 0, 1);
  698.             if (Configurator.displaySide() == DisplaySide.LEFT) {
  699.                 gui.drawTexturedModalRect(gui.getGuiLeft(), y, 51, 0, 4, RIBBON_TILE_SIZE);
  700.             } else {
  701.                 gui.drawTexturedModalRect(gui.getGuiLeft() + gui.getXSize() - 4, y, 81, 0, 4, RIBBON_TILE_SIZE);
  702.             }
  703.             GlStateManager.translate(0, 0, -1);
  704.         } else {
  705.             v = 17;
  706.         }
  707.         if (tiles > 0) {
  708.             if (Configurator.displaySide() == DisplaySide.LEFT) {
  709.                 gui.drawTexturedModalRect(gui.getGuiLeft() - RIBBON_TILE_SIZE, y, 34, v, RIBBON_TILE_SIZE, RIBBON_TILE_SIZE);
  710.             } else {
  711.                 gui.drawTexturedModalRect(gui.getGuiLeft() + gui.getXSize(), y, 34, v, RIBBON_TILE_SIZE, RIBBON_TILE_SIZE);
  712.             }
  713.         }
  714.         for (int t = 1, lastTile = tiles - 1;; t++) {
  715.             int w = t == 1 ? offset : RIBBON_TILE_SIZE;
  716.             if (lastTile > 0) {
  717.                 if (Configurator.displaySide() == DisplaySide.LEFT) {
  718.                     gui.drawTexturedModalRect(x - t * RIBBON_TILE_SIZE, y, 17, v, w, RIBBON_TILE_SIZE);
  719.                 } else {
  720.                     gui.drawTexturedModalRect(x - 0 + t * RIBBON_TILE_SIZE + (t == 1 ? RIBBON_TILE_SIZE - offset : 0), y, 102, v, w, RIBBON_TILE_SIZE);
  721.                 }
  722.             }
  723.             if (t >= lastTile) {
  724.                 w = lastTile == 0 ? w : RIBBON_TILE_SIZE;
  725.                 if (Configurator.displaySide() == DisplaySide.LEFT) {
  726.                     gui.drawTexturedModalRect(x - tiles * RIBBON_TILE_SIZE, y, 0, v, w, RIBBON_TILE_SIZE);
  727.                 } else {
  728.                     gui.drawTexturedModalRect(x - 0 + tiles * RIBBON_TILE_SIZE, y, 119, v, w, RIBBON_TILE_SIZE);
  729.                 }  
  730.                 break;
  731.             }
  732.         }
  733.     }
  734.  
  735.     @HookInvoked(callerClass = InventoryEffectRenderer.class, callerMethods = "drawActivePotionEffects()")
  736.     public static boolean drawActivePotionEffects(InventoryEffectRenderer gui) {
  737.         if (!(gui instanceof GuiContainerCreative)) {
  738.             return true;
  739.         }
  740.         final int texV = 166;
  741.         final int texWidth = 120;
  742.         int leftSpace = gui.getGuiLeft() - 4;
  743.         int widthReduceAmount = Math.max(0, texWidth - leftSpace);
  744.         int texFullWidth = texWidth - widthReduceAmount;
  745.         int texSplitWidth = texFullWidth / 2;
  746.         int x, y = gui.getGuiTop();
  747.         if (Configurator.displaySide() == DisplaySide.LEFT) {
  748.             x = gui.getGuiLeft() + gui.getXSize() + 2;
  749.         } else {
  750.             x = gui.getGuiLeft() - texFullWidth - 2;
  751.         }
  752.         Collection<PotionEffect> collection = gui.mc.player.getActivePotionEffects();
  753.         FontRenderer font = gui.mc.fontRenderer;
  754.         if (!collection.isEmpty()) {
  755.             GlStateManager.disableLighting();
  756.             int yStride = 33;
  757.             if (collection.size() > 5) {
  758.                 yStride = 132 / (collection.size() - 1);
  759.             }
  760.             for (PotionEffect effect : Ordering.natural().sortedCopy(collection)) {
  761.                 Potion potion = effect.getPotion();
  762.                 if (!potion.shouldRender(effect)) {
  763.                     continue;
  764.                 }
  765.                 GlStateManager.color(1, 1, 1);
  766.                 gui.mc.getTextureManager().bindTexture(GuiContainer.INVENTORY_BACKGROUND);
  767.                 gui.drawTexturedModalRect(x, y, 0, texV, texSplitWidth, 32);
  768.                 gui.drawTexturedModalRect(x + texSplitWidth, y, texWidth - texSplitWidth, texV, texSplitWidth, 32);
  769.                 if (potion.hasStatusIcon()) {
  770.                     int icon = potion.getStatusIconIndex();
  771.                     gui.drawTexturedModalRect(x + 6, y + 7, 0 + icon % 8 * 18, 198 + icon / 8 * 18, 18, 18);
  772.                 }
  773.                 potion.renderInventoryEffect(x, y, effect, gui.mc);
  774.                 if (!potion.shouldRenderInvText(effect)) {
  775.                     y += yStride;
  776.                     continue;
  777.                 }
  778.                 String name = I18n.format(potion.getName());
  779.                 int amplifier = effect.getAmplifier();
  780.                 String level;
  781.                 if (amplifier > 0 && amplifier < 4) {
  782.                     level = " " + I18n.format("enchantment.level." + (amplifier + 1));
  783.                 } else {
  784.                     level = "";
  785.                 }
  786.                 int levelWidth = font.getStringWidth(level);
  787.                 name = fitString(font, name, texWidth - widthReduceAmount - 32 - levelWidth) + level;
  788.                 font.drawStringWithShadow(name, x + 28, y + 6, 0xFFFFFF);
  789.                 String remainingTime = Potion.getPotionDurationString(effect, 1);
  790.                 font.drawStringWithShadow(remainingTime, x + 28, y + 16, 0x7F7F7F);
  791.                 y += yStride;
  792.             }
  793.         }
  794.         return false;
  795.     }
  796.  
  797.     private static String fitString(FontRenderer font, String text, int maxWidth) {
  798.         if (font.getStringWidth(text) < maxWidth) {
  799.             return text;
  800.         }
  801.         int width = 0;
  802.         boolean isBold = false;
  803.         String ellipses = "...";
  804.         int boldEllipsesAddition = 3;
  805.         maxWidth -= font.getStringWidth(ellipses);
  806.         StringBuilder result = new StringBuilder();
  807.         for (int i = 0; i < text.length(); ++i) {
  808.             char chr = text.charAt(i);
  809.             int charWidth = font.getCharWidth(chr);
  810.             if (charWidth < 0 && i < text.length() - 1) {
  811.                 chr = text.charAt(++i);
  812.                 if (!isBold && (chr == 'l' || chr == 'L')) {
  813.                     isBold = true;
  814.                     maxWidth -= boldEllipsesAddition;
  815.                 } else if (isBold && (chr == 'r' || chr == 'R')) {
  816.                     isBold = false;
  817.                     maxWidth += boldEllipsesAddition;
  818.                 }
  819.                 charWidth = 0;
  820.             }
  821.             width += charWidth;
  822.             if (isBold && charWidth > 0) {
  823.                 width++;
  824.             }
  825.             if (width > maxWidth) {
  826.                 result.append(ellipses);
  827.                 break;
  828.             }
  829.             result.append(chr);
  830.         }
  831.         return result.toString();
  832.     }
  833. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top