Jump to content

Recommended Posts

Posted

Hi,

 

I'm new to modding but experienced in server plugin development. I have no idea where to start. I'm trying to capture the InventoryOpenEvent so I can output some metadata of the items to a file.

 

This is what I have so far - I can't seem to use @EventHandler . How can I achieve this?

 

package com.example.examplemod;

import org.apache.logging.log4j.Logger;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

@Mod(modid = ExampleMod.MODID, name = ExampleMod.NAME, version = ExampleMod.VERSION)
public class ExampleMod
{
    public static final String MODID = "examplemod";
    public static final String NAME = "Example Mod";
    public static final String VERSION = "1.0";

    private static Logger logger;

    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
        logger = event.getModLog();
    }

    @EventHandler
    public void init(FMLInitializationEvent event)
    {
        logger.info("Client Started");
        // ?
    }
}

 

Posted

Ok, I've read that, but I can't find the right event type - it seems Forge doesn't support it. Isn't the idea to be able to modify the game, ie. change anything you want?

Posted
  On 10/25/2018 at 9:14 PM, AntiRix said:

I can't find the right event type

Expand  

GuiOpenEvent(client) PlayerContainerEvent.Open(server).

Although if the inventory in question isn't synced to the client at all times you need to handle one of the TickEvents(depends on the side you want to perform the actions) and check the current opened container. If it changes start scanning for changes in it's contents(switch a boolean to true or something and if it is true scan the inventory). Once it isn't empty anymore the items have been synced and you can do whatever it is you needed to do.

Posted

I now have a simple setup which is able to detect the inventory opening and closing, but it always says the inventory is empty, probably because the server hasn't sent the items over yet. Should I keep waiting for the inventory to be populated, and if so, how can I know? I can't see any methods related to it.

 

private boolean inventory_open = false;
	
	@SubscribeEvent
	public void onPlayerTick(TickEvent.PlayerTickEvent event)
	{
		GuiScreen screen = Minecraft.getMinecraft().currentScreen;
		
		if (screen instanceof GuiInventory)
		{
			if (inventory_open) return;
			
			inventory_open = true;
			ExampleMod.logger.info("> Inventory opened");
		}
		else
		{
			if (!inventory_open) return;
			
			inventory_open = false;
			ExampleMod.logger.info("> Inventory closed");
			
			return;
		}
		
		Container cont = ((GuiInventory) screen).inventorySlots;
		
		for (int i = 0; i < cont.inventorySlots.size(); i++)
		{
			ExampleMod.logger.info("Slot " + i + ": " + cont.inventorySlots.get(i).getSlotTexture());
		}
	}

 

Posted
  On 10/25/2018 at 10:12 PM, AntiRix said:

PlayerTickEvent

Expand  

This is a common event, meaning it is fired for both the client and the server. You are using client-only classes so you must only subscribe your event handler to the bus on the client.

 

  On 10/25/2018 at 10:12 PM, AntiRix said:

Should I keep waiting for the inventory to be populated, and if so, how can I know?

Expand  

Just wait untill there is at least one item in the inventory. They all get synced at once so as long as there is at least one item there are others there too. Your current code only checks the inventory once on the first tick as it is opened which is probably too early.

 

Also Slot#getSlotTexture returns an ItemStack that is used as the background image for the slot, hence the name. You need Slot#getStack.

 

Also I think that the player's inventory is always known to the client so you can just get whatever is in it in the GuiOpenEvent.

Posted (edited)

I'm already registering the event handler.

 

I'm dealing with custom inventories which servers show, not the normal player inventory

Edited by AntiRix
Posted
  On 10/25/2018 at 10:22 PM, AntiRix said:

I'm already registering the event handler.

Expand  
  On 10/25/2018 at 10:19 PM, V0idWa1k3r said:

only subscribe your event handler to the bus on the client.

Expand  

 

  On 10/25/2018 at 10:22 PM, AntiRix said:

I'm dealing with custom inventories which servers show, not the normal player inventory

Expand  

Are you sure? Because this

  On 10/25/2018 at 10:12 PM, AntiRix said:

GuiInventory

Expand  

Is the player's inventory GUI, and player's only.

Posted

Right, I've changed that to GuiContainer and it's working for those inventories now. The only issue is that when changing inventories by clicking through the custom inventories, there's no tick where the currentScreen isn't an instance of GuiContainer. As such, I either need to compare all of the inventory contents to detect a change, or much easier, detect a change in the inventory title because each has a unique title. I can't find any methods in GuiContainer to get the name or title; are you aware of a way to get it?

 

	private boolean inventory_open = false;
	private boolean inventory_populated = false;
	
	@SubscribeEvent
	public void onPlayerTick(TickEvent.PlayerTickEvent event)
	{
		GuiScreen screen = Minecraft.getMinecraft().currentScreen;
		
		boolean inventory_open_in_tick = screen instanceof GuiContainer;
		
		if (!inventory_open && inventory_open_in_tick)
		{
			inventory_open = true;
			ExampleMod.logger.info("> Inventory opened");			
		}
		
		if (inventory_open && !inventory_open_in_tick)
		{
			inventory_open = false;
			inventory_populated = false;
			ExampleMod.logger.info("> Inventory closed");
			
			return;
		}
		
		if (!inventory_open_in_tick || inventory_populated) return;
		
		// inventory must be open and unpopulated by this point
		
		Container cont = ((GuiContainer) screen).inventorySlots;
		
		for (int i = 0; i < cont.inventorySlots.size(); i++)
		{
			ItemStack stack = cont.inventorySlots.get(i).getStack();
			String name = stack.getItem().getRegistryName().getResourcePath();
			
			if (name != "air")
			{
				inventory_populated = true;
				ExampleMod.logger.info("> Inventory populated");
				
				break;
			}
		}
		
		if (!inventory_populated) return;
		
		// inventory is now populated
		
		for (int i = 0; i < cont.inventorySlots.size(); i++)
		{
			ItemStack stack = cont.inventorySlots.get(i).getStack();
			String name = stack.getItem().getRegistryName().getResourcePath();
			
			ExampleMod.logger.info("> Slot " + i + ": " + name);
		}
	}

 

Posted
  On 10/25/2018 at 10:48 PM, AntiRix said:

I either need to compare all of the inventory contents to detect a change, or much easier, detect a change in the inventory title because each has a unique title.

Expand  

Why not compare container objects themselves?

private static GuiContainer lastInventory;

...

@SubscribeEvent
public static void handler(TickEvent.ClientTickEvent event)
{
	GuiScreen current = Minecraft.getMinecraft().currentScreen;
  	if (current != lastInventory)
    {
    	// Opened GUI changed.
    }
  
  	...
      
    lastInventory = current instanceof GuiContainer ? (GuiContainer)current : null;
}

 

Posted
  On 10/26/2018 at 10:40 AM, diesieben07 said:

You should check for specific GuiContainer instances instead.

Expand  

 

How can I have anything to compare against? All I can go by is the inventory title, or by checking every item inside the inventory. These are custom inventories opened by server plugins.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Yes that’s the full log, I managed to get it working last night, the anvil fix mod is what was causing it to crash
    • Hey guys, i'm currently developping a mod with forge 1.12.2 2860 and i'm using optifine and gradle 4.9. The thing is i'm trying to figure out how to show the player's body in first person. So far everything's going well since i've try to use a shader. The player's body started to blink dark when using a shader. I've try a lot of shader like chocapic, zeus etc etc but still the same issue. So my question is : How should i apply the current shader to the body ? At the same time i'm also drawing a HUD so maybe it could be the problem?   Here is the issue :    And here is the code where i'm trying to display the body :    private static void renderFirstPersonBody(EntityPlayerSP player, float partialTicks) { Minecraft mc = Minecraft.getMinecraft(); GlStateManager.pushMatrix(); GlStateManager.pushAttrib(); try { // Préparation OpenGL GlStateManager.enableDepth(); GlStateManager.depthMask(true); GlStateManager.enableAlpha(); GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1F); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // Éclairage correct pour shaders GlStateManager.enableLighting(); RenderHelper.enableStandardItemLighting(); GlStateManager.enableRescaleNormal(); // Active la lightmap pour les shaders mc.entityRenderer.enableLightmap(); // Position de rendu interpolée double px = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks; double py = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks; double pz = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks; GlStateManager.translate( px - mc.getRenderManager().viewerPosX, py - mc.getRenderManager().viewerPosY, pz - mc.getRenderManager().viewerPosZ ); // Rendu du joueur sans la tête Render<?> render = mc.getRenderManager().getEntityRenderObject(player); if (render instanceof RenderPlayer) { RenderPlayer renderPlayer = (RenderPlayer) render; boolean oldHeadHidden = renderPlayer.getMainModel().bipedHead.isHidden; boolean oldHeadwearHidden = renderPlayer.getMainModel().bipedHeadwear.isHidden; renderPlayer.getMainModel().bipedHead.isHidden = true; renderPlayer.getMainModel().bipedHeadwear.isHidden = true; setArmorHeadVisibility(renderPlayer, false); renderPlayer.doRender(player, 0, 0, 0, player.rotationYaw, partialTicks); renderPlayer.getMainModel().bipedHead.isHidden = oldHeadHidden; renderPlayer.getMainModel().bipedHeadwear.isHidden = oldHeadwearHidden; setArmorHeadVisibility(renderPlayer, !oldHeadwearHidden); } // Nettoyage post rendu mc.entityRenderer.disableLightmap(); GlStateManager.disableRescaleNormal(); } catch (Exception e) { // silent fail } finally { GlStateManager.popAttrib(); GlStateManager.popMatrix(); } }   Ty for your help. 
    • Item successfully registered, but there was a problem with the texture of the item, it did not insert and has just the wrong texture.     
    • Keep on using the original Launcher Run Vanilla 1.12.2 once and close the game Download Optifine and run optifine as installer (click on the optifine jar) Start the launcher and make sure the Optifine profile is selected - then test it again  
    • Hi everyone, I’m hoping to revisit an old version of Minecraft — specifically around Beta 1.7.3 — for nostalgia’s sake. I’ve heard you can do this through the official Minecraft Launcher, but I’m unsure how to do it safely without affecting my current installation or save files. Are there any compatibility issues I should watch out for when switching between versions? Would really appreciate any tips or advice from anyone who’s done this before! – Adam
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.