Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.12.x] Updated GuiTabs PR #4389

Closed
wants to merge 0 commits into from

Conversation

sokratis12GR
Copy link

@sokratis12GR sokratis12GR commented Sep 11, 2017

Updated version of #3642

Modified the code to work with 1.12.x changes

Fixed the java classes having 2 license headers
Removed an useless condition inside GuiTabsMenu.addButtons
And a few minor changes to use += and -= where possible
Improved their functionality
Removed redundant code
Introduced Default Tabs:

  • Added Vanilla Default Tabs (Inside DefaultVanillaGuiTabs.class)

A few refactors (name changes):

  • GuiTabList.class -> GuiTabsMenu.class
  • getLocalizedName -> getUnlocalizedName (thats what it always was getting, users should translate their names)

Location of the GuiTabs has been moved from player.inventory.tabs -> gui.tabs

Any suggestions for improvements are welcome

Known bugs (fixed):

  • The y pos of the paginator
  • Some tabs overlapsing with already added onces
  • wrong number of pages (displays additonal pages with empty/no tabs)
  • When clicking the recipe book, while there are additional tabs the paginator is off place
  • Double Chests Tab's Functionality
  • Player Recipe book support for paginator
  • Crafting Table Recipe book support for paginator

Credits to @ArtixAllMighty for making the original PR and @AshIndigo for updating it to 1.11.x

import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't change imports.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uhm import net.minecraft.client.renderer.texture.TextureMap; appears as not used import

EDIT: oh right its a MC patch

+
import org.lwjgl.input.Keyboard;

+import com.google.common.collect.Sets;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't change imports.

* @param name The name of the tab
* @param icon The icon
*/
@SideOnly(Side.CLIENT)
Copy link
Contributor

@liach liach Sep 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the annotation again once the class is annotated.

*/
public static List<GuiTab> getTabsForGui(Class<? extends GuiContainer> guiContainer)
{
return tabRegistry.containsKey(guiContainer) ? tabRegistry.get(guiContainer) : new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer Collections.emptyList() rather than new ArrayList<>().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is meant to be modifiable, you should simply use get

int size = getTabsForGui(guiContainer.getClass()).size();
if (size > 0)
{
for (int i = 0; size > i; i++)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use an iterator or a stream for this instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that readable enough ?

       if (size > 0)
        {
            IntStream.range(0, size).filter(i ->
                    !getTabsForGui(targetGui).contains(getTabsForGui(guiContainer.getClass()).get(i))
            ).forEach(i ->
                    getTabsForGui(guiContainer.getClass()).get(i).addTo(targetGui)
            );
        }

tabs.addAll(GuiTab.getTabsForGui(this.guiContainer.getClass()));
maxPages = setMaxPages();
getTabs();
for (GuiTab tab : getTabs())// Set the first page
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any point to call getTabs() twice?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, noticed this as well.. removed

this.guiContainer = guiContainer;
this.guiContainerClass = guiContainer.getClass();
tabs = new ArrayList<>(); // get a copy of the stored list so it can be modified without consequence
tabs.addAll(GuiTab.getTabsForGui(this.guiContainer.getClass()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabs = new ArrayList<>(GuiTab.getTabsForGui(this.guiContainer.getClass()));

See ArrayList constructor with a Collection argument.

int end = Math.min(getTabs().size(), (page + 1) * maxTabsPerPage);

for (GuiTab tab : getTabs())
{ // < end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is that comment?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No clue

invS = new InventoryBasic("Test", true, 27);
switch (ID)
{
default:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This indentation is weird...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is fine. It is a test mod, which no one really cares.

}

maxPages = setMaxPages();
for (GuiTab tab : getTabs())// Set the first page
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I replace this with:

page = getTabs().stream().filter(tab -> tab.isActiveTab(guiContainerClass)).findFirst().map(GuiTab::getTabPage).orElse(page);

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it's fine as-is

@sokratis12GR
Copy link
Author

sokratis12GR commented Sep 11, 2017

Currently if there are no other tabs added to the Players' Inventory other than the default one, it will not show the Tab above. but if there are more than 1 tabs (default + other tabs) it will also display the main inventory tab (which it didn't used to do before).
With additional tabs:
image
Without additional tabs:
image

@Override public boolean isActiveTab(Class<? extends GuiContainer> guiContainer)
{
return super.isActiveTab(guiContainer);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this override

private Class<? extends GuiContainer> parentContainer;
private Class<? extends GuiContainer> targetGui;

public static final GuiTab VANILLA_INVENTORY_TAB = new GuiTab("default_inventory", new ItemStack(Items.SKULL, 1, 3))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the skull be user-aware?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but not sure what would be a proper way to do that

ItemStack skull = new ItemStack(Items.SKULL, 1, 3);
skull.setTagCompound(new NBTTagCompound());
NBTTagCompound nbttagcompound = new NBTTagCompound();
NBTUtil.writeGameProfile(nbttagcompound, Minecraft.getMinecraft().getSession().getProfile());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the player skull (with the Player's skin) is only visible in Single Player.
But when joining a server the skull gets replaced with the default (Steve/Alex Skin).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the skull of the client player?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why's it have to be the player's head, can't it just be the default steve head?
it's cool and all but if there's problems with it it's not really worth dealing with

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boy, it is not that hard... You can get a skull of a certain player fairly easily.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean like, the "cool" look will be when the player plays on single player. but when being on a server the default skin (steve/alex) will display. I guess its not that important ?

Also liach, would love to know how I could do that :)

@mezz mezz added 1.12 Feature This request implements a new feature. labels Sep 13, 2017
{
if (parentContainer.equals(GuiContainerCreative.class))
{
FMLLog.log.warn("Cannot add tabs to creative inventory. Use CreativeTabs instead");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should throw an exception instead of logging.

}
else if (parentContainer.equals(InventoryEffectRenderer.class))
{
FMLLog.log.warn(name + " tab has a parent that is ambitious with the creative inventory. cannot proceed with registry.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also throw an exception.

ambitious -> ambiguous?

*/
public GuiTab addTo(Class<? extends GuiContainer> parentContainer)
{
if (parentContainer.equals(GuiContainerCreative.class))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for .equals here, == should be fine.

*
* @author Subaraki, Modified by Ash Indigo
*/
public class GuiTabList
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more than a "List of GuiTabs", isn't it? Is there perhaps a more suitable name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class is responsible for holding a list of GuiTabs and rendering, so I would suggest GuiTabMenu.

FMLLog.log.warn("Cannot add tabs to creative inventory. Use CreativeTabs instead");
return this;
}
else if (parentContainer.equals(InventoryEffectRenderer.class))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.equals -> ==

@sokratis12GR
Copy link
Author

sokratis12GR commented Sep 13, 2017

Found out a few bugs that have to be fixed:

  • The y pos of the paginator
    image
  • lighting of items
    image
  • some tabs overlapsing with already added onces
    image
  • wrong number of pages (displays additonal pages with empty/no tabs)
    image
    image
  • when clicking the recipe book, while there are additional tabs the paginator is off place
    image

@covers1624
Copy link
Contributor

The lighting "issues" are from a forge test mod that i pr'ed, #4127

@sokratis12GR
Copy link
Author

ah so its fine then ?

@covers1624
Copy link
Contributor

Yeah, the lighting issues are from the test mod, put any other block in your inventory.

@JamiesWhiteShirt
Copy link
Contributor

Perhaps the collection of tabs should be purely event based instead? There could be situations where you need to conditionally add a tab, or add a variable amount of tabs.

You could use GuiScreenEvent.InitGuiEvent to append tabs. This way you could also have better control over the order of the tabs.

@@ -95,6 +99,17 @@ public void onTabClicked(GuiContainer guiContainer)
GuiTabsTest.INSTANCE.sendToServer(new TabMessageHandler.TabMessage(0));
}
}.addTo(GuiInventory.class);
ItemStack is = new ItemStack(Items.APPLE);
is.addEnchantment(new net.minecraft.enchantment.EnchantmentProtection(Enchantment.Rarity.COMMON, EnchantmentProtection.Type.FALL), 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use Enchantments.PROTECTION?
You are instantiating a new Enchantment object (like Item, Block, or Potion) without registering it.

{
ctx.getServerHandler().player.openGui(GuiTabsTest.instance, message.id, ctx.getServerHandler().player.world,
ctx.getServerHandler().player.chunkCoordX, ctx.getServerHandler().player.chunkCoordY,
ctx.getServerHandler().player.chunkCoordZ);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the player's chunk coords (world coords / 16). is there any reason they're being used? if the gui handler doesn't need them just pass zeroes instead, it's cleaner.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay, until today I thought they were like a requirement, (I know its stupid but I thought it might need the exact location of the player to open the gui). replaced with 0s

@sokratis12GR
Copy link
Author

sokratis12GR commented Sep 14, 2017

A question/suggestion:

Should there be "default" tabs for the vanilla containers? (Like Creative tabs)
Just so the mods adding don't have to add the "main" page back themselves which could cause in conflicts/duplicated tabs

EDIT: Those tabs could be placed inside like... VanillaGuiTabs or something like that

@sokratis12GR
Copy link
Author

sokratis12GR commented Sep 14, 2017

Random Bug Happening from time to time (While changing tabs rapidly):
image
How to reproduce: Unknown
Fix: first need to find the reason

@sokratis12GR
Copy link
Author

sokratis12GR commented Sep 14, 2017

Important poll vote http://www.strawpoll.me/13927765

@sokratis12GR
Copy link
Author

By the total votes so far, I've decided to make some default tabs for some vanilla containers:
https://imgur.com/a/z6r4z

@Alpvax
Copy link

Alpvax commented Sep 15, 2017

I still like the idea of tab groups which can be added. Could be useful for e.g. charging blocks, where all "equipment" tabs are accessible (for ease of charging).

@mezz
Copy link
Contributor

mezz commented Sep 17, 2017

I think it would be simplest if you just used the chest icon for the default tab, like the "survival inventory" tab does in the Creative GUI.

@sokratis12GR
Copy link
Author

True, but ugh, tbh wouldn't it be better even if MC used the player's skull for the inventory instead of the chest in Creative too?
I don't know.. I wanted it to be something unique but at the same time easy for the player to understand what it is. You guys decide tho.. Please vote with ThumbsUp if you want to keep the player and ThumbsDown if you want to make it the chest icon.

@Alpvax
Copy link

Alpvax commented Sep 18, 2017

The chest icon could mean a different gui (a chest). What happens if someone adds a "portable chest"? Making it a player head reduces confusion

@AbsolemJackdaw
Copy link

Glad to see this is being continued.
This is turning out really well actually.
I hope yours gets merged to forge !

// get a copy of the stored list so it can be modified without consequence
this.guiContainerClass = attachable.getMainGuiContainer().getClass();
List<GuiTab> tabsForGui = GuiTab.getTabsForGui(this.guiContainer.getClass());
GuiTab defaultTab;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the default gui be converted into a private field and have a private setter and a public getter ?

Copy link

@pWn3d1337 pWn3d1337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you just use the vanilla string-keys instead of using your own? That way it would automatically be translated already.

*/
public String getLocalizedName()
{
return "guiGroup." + name;
Copy link

@Alpvax Alpvax Sep 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why "guiGroup" why not "guiTab" or something

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so recommend to change this to guiTab ?
I used guiGroup as in reference of the creative tabs, but a change can be made

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use guiGroup..

@sokratis12GR
Copy link
Author

Hey, I'm really confused about the "main gui automation" progress/mechanics... so here is a Poll, please vote on it... and if there are any questions and things I can do to make it work, ping me on discord sokratis12GR#2764
http://www.strawpoll.me/14257055

@Alpvax
Copy link

Alpvax commented Oct 30, 2017

I think there should be some sort of default that is used if the modder does not implement the interface themselves. Where it would get the icon from I don't know.

@sokratis12GR
Copy link
Author

sokratis12GR commented Oct 31, 2017

Well, I guess that could be achieved if the mod author or someone creates an library/utility mod adding the default tab for the main mod so that other mod authors could add/create addons without conflicts.
I'm really not sure if the current way of doing is if at all functional.
I was many times suggested to switch over to an event system, which I'm sadly not able to do. I don't have the knowledge to create such system. If anyone wants to add the event system feel free to do so.
Hence my current way of doing default tabs is not fully functional and can cause major bugs which shouldn't be existing. Thanks in advance to anyone if they are willing to help :)

@stale
Copy link

stale bot commented Nov 30, 2017

This has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Stale This request hasn't had an update from the author in a long time. label Nov 30, 2017
/**
* Dictates how many tabs per page are drawn
*/
public final static int MAX_TABS_PER_PAGE = 12;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static final

* Dictates how many tabs per page are drawn
*/
public final static int MAX_TABS_PER_PAGE = 12;
private int page;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currentPage?

*/
private Class<? extends GuiContainer> guiContainerClass;
private List<GuiTab> tabs;
private static final ResourceLocation TEXTURE_TABS = new ResourceLocation("textures/gui/container/creative_inventory/tabs.png");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this constant with the max page numbers?

*
* @author Subaraki, Modified by Ash Indigo
*/
public class GuiTabMenu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be extended? If yes, you may consider leaving some fields protected.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure. If so, which fields would be best to be protected ?

* Adds 25 tabs to the player inventory and 13 to a test gui Also checks if item stack icon and ResourceLocation icons are working
*/
@Mod(name = "GuiTabsTest", modid = "guitabtest", version = "0.0.0.0")
@EventBusSubscriber()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need parentheses

private static ListMultimap<Class<? extends GuiContainer>, GuiTab> tabRegistry = ArrayListMultimap.create();

private ItemStack iconStack = ItemStack.EMPTY;
private ResourceLocation iconResLoc = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nullable

private String name;
private Class<? extends GuiContainer> parentContainer;
private Class<? extends GuiContainer> targetGui;
private static Minecraft mc = Minecraft.getMinecraft();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should make fields protected since they are actively accessed in both this and the subclasses.

private Class<? extends GuiContainer> targetGui;
private static Minecraft mc = Minecraft.getMinecraft();

public static final GuiTab VANILLA_INVENTORY_TAB = new GuiTab(null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving these mess into another utility class to make things neater?

*
* @param name The name of the tab
*/
private GuiTab(String name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you move them into another class, you can make this package private so that mods cannot use it.

@stale stale bot removed the Stale This request hasn't had an update from the author in a long time. label Dec 1, 2017
@liach
Copy link
Contributor

liach commented Dec 1, 2017

Seems that commits are somewhat messed up

@sokratis12GR
Copy link
Author

sokratis12GR commented Dec 2, 2017

Dunno what happened. Tho I've asked about this at Mezz's Discord Server, I've been told that it should be alright (Shouldn't have any impact other than the PR's GuiTabs).

@mezz
Copy link
Contributor

mezz commented Dec 2, 2017

The file changes here include things you never edited, it needs to be fixed.
You should probably rebase on to the latest 1.12.x and push to a new branch with a new PR.
Let me know if you need a hand.

@sokratis12GR
Copy link
Author

Ugh, for the time being please ignore my commits, trying to solve things out and will make as you said a completely new PR from a branch and not master.

@HenryLoenwind
Copy link

I'm no git expert, but I'd say: Don't merge the origin changes into your branch but rebase your branch onto the the origin branch.

@diesieben07
Copy link
Contributor

I'm no git expert, but I'd say: Don't merge the origin changes into your branch but rebase your branch onto the the origin branch.

This. Merging in a PR usually causes nothing but problems.

@liach
Copy link
Contributor

liach commented Dec 2, 2017

So the actual difference is here:
1.12.x...sokratis12GR:1.12.x

I agree that github is a little bit fuzzy here.

@sokratis12GR
Copy link
Author

BTW, I think I found what was causing the weird recipe book thing with the crafting table container.
The GuiCrafting wasn't calling super on actionPerformed so it was ignoring the change.

@sokratis12GR
Copy link
Author

sokratis12GR commented Dec 5, 2017

After some discussion in Mezz's discord server. There was a decision to not include automatic generation of default gui tabs. If a mod, gui container wants to have a default tab, they should register the gui tab inside the gui container's constructor.
The PR is pretty much complete. Let me know if there are more things to be done.

@AbsolemJackdaw
Copy link

I'd love to see this pr come to a merge in forge ... !
So much time and work has been put into this.
Thanks for pulling the idea all the way trough to the end sokratis12GR !!

@sokratis12GR
Copy link
Author

sokratis12GR commented Jan 4, 2018

Oh, another thing I would like to note, is should the methods be renamed according to: ModCoderPack/MCPBot-Issues#565 ?
Example:

fields:
iconResLoc -> iconRL

methods:
getTabIndex -> getIndex
getTabPage -> getPage
getIconResLoc -> getIconRL

@liach
Copy link
Contributor

liach commented Jan 4, 2018

@sokratis12GR I think you can name the methods whatever you want. Those name changes might be applied at any time, and does not affect the compiling of forge.

@sokratis12GR
Copy link
Author

sokratis12GR commented Jan 4, 2018

@liach, I edited my comment, but really would like to know if I should do the changes, for like the main ones
getTabIndex -> getIndex
getTabPage -> getPage

@sokratis12GR
Copy link
Author

Will create a new PR (fixing the Commit history).
Please ignore any commits to this PR after this comment (updating master <1.12.2>), will create this PR from a branch

@sokratis12GR
Copy link
Author

This PR has been closed in favor of #4654.
Please any future conversations to be done in the other (clean) PR :)

@mezz mezz added the Superseded This request has a more updated, more capable, and overall better alternative. label Jan 5, 2018
CDAGaming pushed a commit to CDAGaming/MinecraftForge that referenced this pull request Jan 22, 2018
CDAGaming pushed a commit to CDAGaming/MinecraftForge that referenced this pull request Jan 24, 2018
CDAGaming pushed a commit to CDAGaming/MinecraftForge that referenced this pull request Jan 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.12 Feature This request implements a new feature. Superseded This request has a more updated, more capable, and overall better alternative.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet