Advertisement
Guest User

Untitled

a guest
May 25th, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.01 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement