Jump to content

The_Fireplace

Forge Modder
  • Posts

    243
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by The_Fireplace

  1. Ok, so my issue is that in the Config Gui, I have a config option which I used a class extending GuiConfigEntries.SelectValueEntry as the Gui for. When I click the option to open the Gui, it looks like this:

     

     

    r3rDuBt.png

     

     

    However, in the example given by FML, the Gui adjusted so the title didn't overlap with the options, like this:

     

     

    uWDSHUS.png

     

     

    Now, for my code:

     

     

    OreGenEntries.class(The file extending GuiConfigEntries.SelectValueEntry)

    public class OreGenEntries extends GuiConfigEntries.SelectValueEntry {
    
    public OreGenEntries(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement configElement) {
    	super(owningScreen, owningEntryList, configElement, ClaySpawn.instance.entries);
    }
    }
    

    My main mod file:

    /**
    * @author The_Fireplace
    */
    @Mod(modid=ClaySpawn.MODID, name=ClaySpawn.MODNAME, version=ClaySpawn.VERSION, acceptedMinecraftVersions = "1.8", guiFactory = "the_fireplace.clayspawn.config.ClaySpawnGuiFactory")
    public class ClaySpawn {
    @Instance(ClaySpawn.MODID)
    public static ClaySpawn instance;
    public static final String MODID = "clayspawn";
    public static final String MODNAME = "Fire's Clay Spawn";
    public static final String VERSION = "2.2.1.0";
    public static final String downloadURL = "http://goo.gl/vi8Kom";
    
    public WorldGeneratorClay wg = new WorldGeneratorClay();
    public Map entries = Maps.newHashMap();
    
    public static Configuration file;
    public static Property OREGENRATE_PROPERTY;
    public static Property DENSITYOVERRIDE_PROPERTY;
    public static Property HEIGHTOVERRIDE_PROPERTY;
    
    public static void syncConfig(){
    	ConfigValues.OREGENRATE = OREGENRATE_PROPERTY.getString();
    	ConfigValues.DENSITYOVERRIDE = DENSITYOVERRIDE_PROPERTY.getInt();
    	ConfigValues.HEIGHTOVERRIDE = HEIGHTOVERRIDE_PROPERTY.getInt();
    	if(file.hasChanged()){
    		file.save();
    	}
    }
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
    	CSAPI.registerOre("iron", 65, ;
    	CSAPI.registerOre("coal", 128, 16);
    	CSAPI.registerOre("diamond", 15, 7);
    	CSAPI.registerOre("gold", 32, ;
    	CSAPI.registerOre("emerald", 32, 1);
    	CSAPI.registerOre("lapis", 31, 6);
    	CSAPI.registerOre("redstone", 16, 7);
    	//Mod Ores
    	CSAPI.registerOre("unlogicii:fossil", 12, 2);
    	CSAPI.registerOre("clayspawn:clayworld", 255, 32);
    	FMLCommonHandler.instance().bus().register(new FMLEvents());
    	file = new Configuration(event.getSuggestedConfigurationFile());
    	file.load();
    	OREGENRATE_PROPERTY = file.get(Configuration.CATEGORY_GENERAL, ConfigValues.OREGENRATE_NAME, ConfigValues.OREGENRATE_DEFAULT, StatCollector.translateToLocal(ConfigValues.OREGENRATE_NAME+".tooltip"));
    	DENSITYOVERRIDE_PROPERTY = file.get(Configuration.CATEGORY_GENERAL, ConfigValues.DENSITYOVERRIDE_NAME, ConfigValues.DENSITYOVERRIDE_DEFAULT, StatCollector.translateToLocal(ConfigValues.DENSITYOVERRIDE_NAME+".tooltip"));
    	HEIGHTOVERRIDE_PROPERTY = file.get(Configuration.CATEGORY_GENERAL, ConfigValues.HEIGHTOVERRIDE_NAME, ConfigValues.HEIGHTOVERRIDE_DEFAULT, StatCollector.translateToLocal(ConfigValues.HEIGHTOVERRIDE_NAME+".tooltip"));
    	OREGENRATE_PROPERTY.setConfigEntryClass(OreGenEntries.class);
    	syncConfig();
    }
    }
    

    And finally, ClaySpawnConfigGui.class

    /**
    * @author The_Fireplace
    */
    public class ClaySpawnConfigGui extends GuiConfig{
    public ClaySpawnConfigGui(GuiScreen parentScreen) {
    	super(parentScreen,
    			new ConfigElement(ClaySpawn.file.getCategory(Configuration.CATEGORY_GENERAL)).getChildElements(), ClaySpawn.MODID, true,
    			false, GuiConfig.getAbridgedConfigPath(ClaySpawn.file.toString()));
    }
    }
    

     

     

    Now, does anyone know how I can fix this? Or did I do it correctly, and this is an FML bug?

  2. In your post, you are referencing the cache of skins, but you only need to do that if you are hijacking a skin.

     

    Do you want the player to have a default list of skins of your picking or do you want to just give him the skin of some other player you are dynamically picking?

     

    The first is easier.  Just look at how zombies or whatever have a static skin referenced and do that for getting the resourcelocation instead of the the current method.

    Yes, I know the first one is easier, but the goal here is to download the player's skin while they are connected to the internet(I have that part working, so I didn't show it there with my code), and apply it to the player when the player starts the game and they are offline. So yeah, it has to be dynamic.

  3. It is, and if you read attached issue, you'd see that it works without buildcraft. qRc-kUJPAtkFebje6FSNkxByUM59n4xprccD_wNKz_s?size=1280x960&size_mode=2

    First of all, redistributing other mods' APIs within your own mod is a terrible idea. If you are trying to make your mod integrate with the other mods without requiring them, using the APIs is fine, but don't directly access them, and don't redistribute them within your mod.

  4. Hey guys, I am trying to make the player's skin change, on the client side only, in single player. I have tried 2 methods, the first of which does nothing, and the second has an error in the console to go with it not working.

    Yes, I have the skin named correctly at the path I pointed the code to.

    First method: Trying to replace RenderPlayer with a custom one during RenderPlayerEvent.Pre

     

     

    My Main Mod File

    @SideOnly(Side.CLIENT)
    @Mod(modid=SaveMySkin.MODID, name=SaveMySkin.MODNAME, version=SaveMySkin.VERSION, clientSideOnly=true)
    public class SaveMySkin {
    public static final String MODID = "savemyskin";
    public static final String MODNAME = "Save My Skin";
    public static final String VERSION = "2.0.0.1";
    @Instance(MODID)
    public static SaveMySkin instance;
    
    public static final File skindir = new File((File)FMLInjectionData.data()[6], "cachedskins/");
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event){
    	try {
    		Files.createDirectory(skindir.toPath());
    	} catch (IOException e) {}
    	((SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).reloadResourcePack(new DummyResourcePack());
    	MinecraftForge.EVENT_BUS.register(this);
    }
    @SubscribeEvent
    public void renderPlayer(RenderPlayerEvent.Pre event){
    	ReflectionHelper.setPrivateValue(RenderManager.class, Minecraft.getMinecraft().getRenderManager(), new ReRenderPlayer(Minecraft.getMinecraft().getRenderManager()), "field_178637_m");
    }
    }
    

    ReRenderPlayer.class

    public class ReRenderPlayer extends RenderPlayer {
    
    public ReRenderPlayer(RenderManager renderManager) {
    	super(renderManager);
    }
    @Override
    protected ResourceLocation getEntityTexture(Entity entity)
    {
    	return new ResourceLocation(SaveMySkin.MODID, String.format("%s.png", Minecraft.getMinecraft().getSession().getUsername()));
    }
    }
    

    DummyResourcePack.class

    public class DummyResourcePack extends FileResourcePack {
    
    public DummyResourcePack() {
    	super(new File((File)FMLInjectionData.data()[6], "cachedskins/"));
    }
    @Override
    public String getPackName()
    {
    	return SaveMySkin.MODID;
    }
    }
    

     

     

    Method 2: Replace the skin during ClientConnectedToServerEvent

     

     

    Main Mod File:

    @SideOnly(Side.CLIENT)
    @Mod(modid=SaveMySkin.MODID, name=SaveMySkin.MODNAME, version=SaveMySkin.VERSION, clientSideOnly=true)
    public class SaveMySkin {
    public static final String MODID = "savemyskin";
    public static final String MODNAME = "Save My Skin";
    public static final String VERSION = "2.0.0.1";
    @Instance(MODID)
    public static SaveMySkin instance;
    
    public static final File skindir = new File((File)FMLInjectionData.data()[6], "cachedskins/");
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event){
    	try {
    		Files.createDirectory(skindir.toPath());
    	} catch (IOException e) {}
    	FMLCommonHandler.instance().bus().register(this);
    }
    @SubscribeEvent
    public void onPlayerLogin(final ClientConnectedToServerEvent event) {
    	(new Thread() {
    		@Override
    		public void run() {
    			while (Minecraft.getMinecraft().getTextureManager() == null || Minecraft.getMinecraft().thePlayer == null){
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    				}
    			}
    			EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
    			TextureManager texturemanager = Minecraft.getMinecraft().getTextureManager();
    			ITextureObject textureObject = texturemanager.getTexture(player.getLocationSkin());
    
    			if (textureObject == null) {
    				textureObject = new ThreadDownloadImageData((File) null, String.format("http://skins.minecraft.net/MinecraftSkins/%s.png", Minecraft.getMinecraft().getSession().getUsername()), player.getLocationSkin(), new ImageBufferDownload());
    				texturemanager.loadTexture(player.getLocationSkin(), textureObject);
    			}
    			try {
    				TextureUtil.uploadTextureImage(textureObject.getGlTextureId(), ImageIO.read(new File(skindir, Minecraft.getMinecraft().getSession().getUsername()+".png")));
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}).start();
    }
    

    Error(It doesn't crash):

    Exception in thread "Thread-14" [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: net.minecraft.util.ReportedException: Registering texture
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:92)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at the_fireplace.savemyskin.SaveMySkin$1.run(SaveMySkin.java:109)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: Caused by: java.lang.RuntimeException: No OpenGL context found in the current thread.
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at org.lwjgl.opengl.GLContext.getCapabilities(GLContext.java:124)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at org.lwjgl.opengl.GL11.glGenTextures(GL11.java:1403)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.GlStateManager.generateTexture(GlStateManager.java:332)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.texture.TextureUtil.glGenTextures(TextureUtil.java:36)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.texture.AbstractTexture.getGlTextureId(AbstractTexture.java:57)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.ThreadDownloadImageData.getGlTextureId(ThreadDownloadImageData.java:62)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.texture.SimpleTexture.loadTexture(SimpleTexture.java:58)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.ThreadDownloadImageData.loadTexture(ThreadDownloadImageData.java:79)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:70)
    [22:40:48] [Thread-14/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: 	... 1 more
    

    SaveMySkin.java is my main mod file, line 109 is

    texturemanager.loadTexture(player.getLocationSkin(), textureObject);
    

    to make it easier to find in the code above, here is it and the surrounding lines

    if (textureObject == null) {
    				textureObject = new ThreadDownloadImageData((File) null, String.format("http://skins.minecraft.net/MinecraftSkins/%s.png", Minecraft.getMinecraft().getSession().getUsername()), player.getLocationSkin(), new ImageBufferDownload());
    				texturemanager.loadTexture(player.getLocationSkin(), textureObject);
    			}
    

    I think method 1 is closer to getting it right than this one.

     

     

    I apologize if how I am going about this is completely wrong or I am making a simple mistake; it is late and I have only been working on this for an hour or two.

     

    Any help is appreciated.

  5. Find the exact event that is rendering the text (i think there was getElementsType or sth like that) cancel that event and do the rendering of it on your own (except for the text of course)

    Ok, tried that, it is not cancelable.

    EDIT: It appears that only Post is not cancelable, I will mess with it some more.

    I don't think there is an event for that specifically. The game just renders the item's name. Why do you want an event to be called when changing items, or as you said when the hotbar text changes?

     

    There is the class minecraftforge.client.gui.GuiInGameForge. It has all the gui render events and one is renderHUDText. I've never checkout what it actually renders on the screen.

    I want an event to be called there so I can easily fill in item names. If I do it this way, it uses 41 less lines in the lang files(at the moment, it could save even more later) than the vanilla method. I already did this for the items' tooltips(see spoiler below), now I just need to do it for the name that shows up when changing items.

     

    @SubscribeEvent
    public void tooltipEvent(ItemTooltipEvent event){
    	Item item = event.itemStack.getItem();
    	if(item instanceof FluidityItemChestChanger){
    		FluidityItemChestChanger item2 = (FluidityItemChestChanger)item;
    		event.toolTip.clear();
    		event.toolTip.add(String.format(StatCollector.translateToLocal("fluidity.upgrade"), StatCollector.translateToLocal("fluidity."+item2.getSourceName().toLowerCase()), StatCollector.translateToLocal("fluidity."+item2.getTargetName().toLowerCase())));
    	}
    }
    

     

    As for the class minecraftforge.client.gui.GuiInGameForge, I was unable to find it.

  6. Hey guys, I am trying to get a list of OreDictionary names for an item and render it in the item's tooltip. I have the following code so far:

     

    @SubscribeEvent
    public void tooltipEvent(ItemTooltipEvent event){
    	String[] oreDict = getOreNames(event.itemStack);
    	for(int i=0;i<oreDict.length;i++){
    		event.toolTip.add(EnumChatFormatting.GREEN+oreDict[i]);
    	}
    }
    public String[] getOreNames(ItemStack stack){
    	int[] ids = OreDictionary.getOreIDs(stack);
    	String[] list = new String[ids.length];
    	for(int i=0;i<ids.length;i++){
    		list[i] = OreDictionary.getOreName(i);
    	}
    	return list;
    }
    

     

    When moused over, anything with 1 oredictionary name says logWood, anything with 2 says logWood and plankWood, and I haven't tested anything with 3 or more, as nothing in vanilla Minecraft has that many.

    Does anyone know how I can fix this? Any help is appreciated.

     

    EDIT: Fixed it. Here is the fixed code if anyone wants to see it:

     

    @SubscribeEvent
    public void tooltipEvent(ItemTooltipEvent event){
    	event.toolTip.add(EnumChatFormatting.BLUE+modThatAddedStack(event.itemStack));
    	String[] oreDict = getOreNames(event.itemStack);
    	for(int i=0;i<oreDict.length;i++){
    		event.toolTip.add(EnumChatFormatting.GREEN+oreDict[i]);
    	}
    }
    public String[] getOreNames(ItemStack stack){
    	int[] ids = OreDictionary.getOreIDs(stack);
    	String[] list = new String[ids.length];
    	for(int i=0;i<ids.length;i++){
    		list[i] = OreDictionary.getOreName(ids[i]);
    	}
    	return list;
    }

     

  7. I'm not sure what your MiscTools#areItemStacksEqual implementation is like (or why you would even need one when the ItemStack class itself already offers several ways to check equality), but if your headgear can be damaged, I highly doubt it will ever return true.

     

    Not only that, but unless your item requires stack damage or NBT to determine equality, you are wasting a lot of effort.

    // this monstrosity:
    MiscTools.areItemStacksEqual(new ItemStack(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(4).getItem()), new ItemStack(UnLogicII.crystal_eye_headband)
    
    // should be rewriten as:
    Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(4).getItem() == UnLogicII.crystal_eye_headband
    

    Also, why not store a reference to Minecraft, either in your class or locally in the method, so you don't have such long-winded statements?

     

    Finally, this:

    byte i = 0;
          if(i < 40){
             i++;
          } else {
    

    What are you expecting to happen there? You initialize i to zero EVERY SINGLE TIME the method is called, so i++ is completely pointless and your 'else' statement is never called.

    The first part, I figured out in the time I was waiting for a response. The second part, I didn't notice, I put the byte in the wrong spot. Thanks.

     

    Now, for anyone else trying to do this, here is my completed, working code:

    byte i = 0;
    @SideOnly(Side.CLIENT)
    @SubscribeEvent
    public void onRenderTick(RenderTickEvent t){
    	Minecraft mc = Minecraft.getMinecraft();
    	if(mc.inGameHasFocus){
    		if(mc.thePlayer.getHeldItem() != null)
    			if(mc.thePlayer.getHeldItem().getItem() == Item.getItemFromBlock(UnLogicII.coal_gun) || mc.thePlayer.getHeldItem().getItem() == Item.getItemFromBlock(UnLogicII.smart_coal_gun)){
    				mc.ingameGUI.drawString(Minecraft.getMinecraft().fontRendererObj, StatCollector.translateToLocal("info.coal_type")+": "+StatCollector.translateToLocal(EnumAmmo.getItem(ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer).getAmmoType()).getUnlocalizedName()+".name"), 1, 1, 16777215);
    			}
    	}
    	if(mc.thePlayer != null)
    	if(mc.thePlayer.getEquipmentInSlot(4) != null)
    	if(mc.thePlayer.getEquipmentInSlot(4).getItem() == UnLogicII.crystal_eye_headband){
    	if(i < 40){
    		i++;
    	}else{
    		World world = mc.thePlayer.worldObj;
    		AxisAlignedBB aabb = mc.thePlayer.getEntityBoundingBox().expand(8, 8, ;
    		List entities = world.getEntitiesWithinAABBExcludingEntity(mc.thePlayer, aabb);
    		for(int j=0;j<entities.size();j++){
    			Random rand = new Random();
    			Entity entity = (Entity)entities.get(j);
    			mc.theWorld.spawnParticle(EnumParticleTypes.SPELL_MOB, entity.posX, entity.posY, entity.posZ, (rand.nextDouble() - 0.5D) * (double)entity.width, rand.nextDouble() * (double)entity.height, (rand.nextDouble() - 0.5D) * (double)entity.width, null);
    		}
    		i = 0;
    	}
    	}
    }
    

  8. I want to spawn particles around every living entity within a radius around the player, only if they have a certain headgear equipped. That being said, I don't want them visible to other players not wearing the headgear. I think the simplest way to do this would be to spawn them on the client-side only.

    Now to the problem. I tried coding this, and it was a failure. The player couldn't see the particles. Now for my code:

    In my FMLEvents.class, which is registered to the FML Event bus:

     

     

    @SideOnly(Side.CLIENT)

    @SubscribeEvent

    public void onRenderTick(RenderTickEvent t){

    if(Minecraft.getMinecraft().thePlayer != null)

    if(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(4) != null)

    if(MiscTools.areItemStacksEqual(new ItemStack(Minecraft.getMinecraft().thePlayer.getEquipmentInSlot(4).getItem()), new ItemStack(UnLogicII.crystal_eye_headband))){

    byte i = 0;

    if(i < 40){

    i++;

    }else{

    List entities = Minecraft.getMinecraft().theWorld.getEntitiesWithinAABBExcludingEntity(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().thePlayer.getBoundingBox().expand(8, 8, 8));

    for(int j=0;j<entities.size();j++){

    Random rand = new Random();

    Entity entity = (Entity)entities.get(j);

    Minecraft.getMinecraft().theWorld.spawnParticle(EnumParticleTypes.SPELL_MOB, entity.posX, entity.posY, entity.posZ, (rand.nextDouble() - 0.5D) * (double)entity.width, rand.nextDouble() * (double)entity.height, (rand.nextDouble() - 0.5D) * (double)entity.width, null);

    }

    i = 0;

    }

    }

    }

     

     

     

    Am I doing this completely wrong, or have I just messed up a small portion of it? Any help is appreciated.

  9. I have followed coolAlias's packet tutorial, and I set it up so a packet is sent to the server when a key is pressed. When the key was pressed, I encountered this crash:

     

     

    [16:49:24] [Netty Server IO #1/ERROR] [FML]: FMLIndexedMessageCodec exception caught

    io.netty.handler.codec.DecoderException: java.lang.NullPointerException: Undefined message for discriminator 0 in channel unlogicii

    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.15.Final]

    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]

    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.15.Final]

    at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:88) [FMLProxyPacket.class:?]

    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:144) [NetworkManager.class:?]

    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:469) [NetworkManager.class:?]

    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:412) [NetworkDispatcher.class:?]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:240) [NetworkDispatcher.class:?]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:50) [NetworkDispatcher.class:?]

    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]

    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354) [singleThreadEventExecutor.class:4.0.15.Final]

    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) [NioEventLoop.class:4.0.15.Final]

    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [singleThreadEventExecutor$2.class:4.0.15.Final]

    at java.lang.Thread.run(Unknown Source) [?:1.8.0_45]

    Caused by: java.lang.NullPointerException: Undefined message for discriminator 0 in channel unlogicii

    at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:77) ~[FMLIndexedMessageToMessageCodec.class:?]

    at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]

    at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.15.Final]

    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.15.Final]

    ... 25 more

    [16:49:24] [Netty Server IO #1/ERROR] [FML]: There was a critical exception handling a packet on channel unlogicii

    io.netty.handler.codec.DecoderException: java.lang.NullPointerException: Undefined message for discriminator 0 in channel unlogicii

    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.15.Final]

    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) ~[DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) ~[DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) ~[DefaultChannelPipeline.class:4.0.15.Final]

    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.15.Final]

    at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:88) [FMLProxyPacket.class:?]

    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:144) [NetworkManager.class:?]

    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:469) [NetworkManager.class:?]

    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:412) [NetworkDispatcher.class:?]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:240) [NetworkDispatcher.class:?]

    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:50) [NetworkDispatcher.class:?]

    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]

    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]

    at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]

    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354) [singleThreadEventExecutor.class:4.0.15.Final]

    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) [NioEventLoop.class:4.0.15.Final]

    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [singleThreadEventExecutor$2.class:4.0.15.Final]

    at java.lang.Thread.run(Unknown Source) [?:1.8.0_45]

    Caused by: java.lang.NullPointerException: Undefined message for discriminator 0 in channel unlogicii

    at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:77) ~[FMLIndexedMessageToMessageCodec.class:?]

    at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]

    at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.15.Final]

    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.15.Final]

    ... 25 more

     

     

    And my code:

    The Packet Dispatcher:

    https://bitbucket.org/The_Fireplace/unlogic-ii/src/fed9cdf24bd839485aac7f9ce3cee887bb761449/src/main/java/the_fireplace/unlogicii/network/PacketDispatcher.java?at=master

     

    Any other code you need to see is there in the repository. Let me know if you have any other questions. Any help is very much appreciated.

  10. Yes, you have to send a packet. You ALWAYS need to send a packet when you are performing actions on the client that need to impact the world in some way, including which item will be consumed, etc.

     

    Never set a value on the client that has a correlating value on the server; instead, tell the server what the player wants to do, then let the server decide the value and inform the client player what that value is. E.g.:

     

    1. Player wants to change ammo, presses 'R'

    2. Key handler sends packet to server saying 'Player A pressed the change ammo key, now what?'

    3. Server receives packet, determines player A's next ammo type

    4. Server sends packet back to player A on the client side, saying 'Your new ammo type is X'

     

    That's how your program flow should go, always, for things like this.

     

    As for tutorials / explanations, did you try Google? There is a tutorial by diesieben07 right here in this forum in the Tutorials section, and I have one over on MCF that does things somewhat differently, but I have improved upon it quite a lot since I wrote that tutorial and haven't gotten around to updating it.

    Actually, after posting that, I went ahead and searched for a tutorial, and found the tutorials by you and diesieben. I read diesieben's first, and followed along, though I did encounter the annoyances which I later learned that your tutorial addressed. Also, according to what you just said, I set up the flow wrong, so I will have to go back and fix that when I follow your tutorial. If it isn't too much to ask, since you said you have made improvements to it, and just haven't updated it, can you update your tutorial?

  11. It seems that when the player changes the ammo type they are on, it doesn't send that information to the server. That explains why the items disappear on the client side only, because the server is trying to use the default, but the client thinks they are being consumed, and why, if you have coal and the ammo you are trying to use, coal gets spawned instead of the ammo type you are on, and when you relog, the coal is missing from that. Big moment of realization I just had there. The explaination fits perfectly. Now for how to fix it. I am guessing this will require me to send a packet to the server when the player changes ammo type. Does anyone have a link to a 1.8 tutorial on how to do this, or want to explain it?

  12. There is no reason to be sorry, Tbh, I love it when people take the time to explain a better way of doing things than what I have. I will look in to what you have said and see about a redesign. The reason it is stored with the extendedplayer is so it stays consistant. This way, a player can disconnect and join again later, with the coal type they are on staying the same.

    Isn't the type of ammo the player is using based on what they have in their inventory? Or are they selecting it from somewhere? If the latter, that would make sense to store it like you have.

     

    I had a look at your main class' registerEntity method, and there are a few things wrong with it:

    1. Don't register your entity with a global entity ID - that is for vanilla only

    2. If you don't need a spawn egg, there is even more reason not to use global entity ID, as that is its only benefit (well, and the /summon command)

    3. Tracking update frequency and range values should be set based on the type of entity you are registering, not as a blanket value for all of them. Furthermore, NO vanilla entity uses an update frequency of 1, and you should not either. Always choose values closest to the most closely related vanilla entity you can find.

     

    You can find tracking values in EntityTracker, or online https://docs.google.com/spreadsheets/d/1nqqieNkw9r4NfI-WypIvgeuZnYB4_QU7BcDXptgzqnM/pub?single=true&gid=0&output=htmlhere, though I don't know when it was last updated. Generally, projectiles (except for arrows, for some reason) use (64, 10) and mobs / animals use (80, 3).

    Thanks for the information about registering entities, I will fix that. And the ammo is based on what the player has it set to, if they haven't set it yet, it is regular coal, they can press R at any time to change to the next type. The order is Coal, Charged Coal, Destabilized Coal, Restabilized Coal, Refined Coal, and then it goes back to Coal whewhen pressed again. The smart coal gun, when fired, automatically detects if you don't have any coal of the type of ammo you are on and, if you have any valid coal types in the inventory, it switches the player to the next coal type until it can fire. With the regular coal gun, the player has to select it, there is no automatic switching.

  13. Okay. As for the problem of not properly consuming the item, is that part is outside of the if(!world.isRemote) checker. As for the entity you might not have registered the entity properly (or at all), or maybe the applied the rendering wrong and it is spawning.

    I will look again, I am fairly certain the entity is registered properly. As for the fact that it is outside the !world.isRemote, that just means it would be removed on both the server and client, and not only on the server, leaving behind ghost items in the inventory. As for the rendering, I know for sure that that is not the issue.

    Have you tried using your IDE's debugger? The problem is likely simply one of logic, i.e. a value is not what you expect it to be.

     

    Furthermore, simplifying / rewriting your logic would likely help make things clearer. I don't really see the point of all those conditions in your while loop, for example:

    // Is it really necessary to store the ammo type in ExtendedPlayer? Why can't you just fetch it each time you right click?
    EnumAmmo ammo = ExtendedPlayer.get(playerIn).getAmmoType(); // can this ever return null?
    // This loop already changes the item each time, making all those conditionals redundant and messy
    // Also, you have an EnumAmmo instance on hand, so why make static methods when you can use the instance itself?
    // E.g. ammo.getItem() instead of EnumAmmo.getItem(ammo)
    while (!playerIn.inventory.hasItem(ammo.getItem())) {
    // no need to involve player here, just fetch the next ammo type and see if the player has it
    ammo = ammo.getNext());
    // You will need, however some way to stop the loop, e.g. if ammo loops back around to its original value, set it to null and break
    }
    if (ammo == null) {
    return itemStackIn;
    }
    // set the ExtendedPlayer ammo value at this point, if you still want to do that
    ExtendedPlayer.get(player).setAmmo(ammo);
    // You've already checked that the player has the item needed, right? Don't need to check again, then.
    YourCoalEntity entity = ammo.getCoalEntity(worldIn, playerIn); // make your Enum do some work for you
    if (entity != null && !worldIn.isRemote) {
    worldIn.spawnEntityInWorld(entity);
    // ammo already knows the item, right? So why hard code them all?
    playerIn.inventory.consumeInventoryItem(ammo.getItem());
    }
    return itemStackIn;
    

    You could probably even consolidate all of those different entities into one class, depending on how different they are, simply by setting different class attributes based on the ammo type: setDamage(based on ammo type), setVelocity(based on ammo type), etc.

     

    Sorry I kind of went off on a tangent, there, but I think it would be worth your while to do some refactoring here. In the meantime, you should be able to pinpoint your issue by using the debugger.

    There is no reason to be sorry, Tbh, I love it when people take the time to explain a better way of doing things than what I have. I will look in to what you have said and see about a redesign. The reason it is stored with the extendedplayer is so it stays consistant. This way, a player can disconnect and join again later, with the coal type they are on staying the same.

  14. Not working, I cant publish to the server

    Once you have that done, to push to the server, you first need to commit your changes, then, push them to the server. In source tree, when you push to the server for the first time, you will have to check the box next to the word master.

  15. I stopped modding a year ago due to exams and the 1.7 update meaning that the way i generate schematics no longer works due to the fact that schematics store block ID's which as i understand are not relevant to forge post 1.6

     

    After a few hours of searching i have been unable to find a solution and as my mod uses hundreds of schematic files i am not sure what to do. I am an amateur and a year away from modding has not helped so any help or light you may be able to shed on the issue would be greatly appreciated.

     

    This is the code used to generate the schematic files:

     

     

    public class Loader {

     

    public byte[] blocks;

    public byte[] datablocks;

    public short width;

    public short length;

    public short height;

    public short[] sizes;

     

    public Loader(String path) {

    blocks = null;

    datablocks = null;

    width = 0;

    length = 0;

    height = 0;

    load(path);

    }

     

    public void load(String path) {

    try {

    InputStream inputstream = Loader.class.getResourceAsStream("/assets/warsmod/structures/" + path);

    NBTTagCompound nbt = CompressedStreamTools.readCompressed(inputstream);

     

    blocks = nbt.getByteArray("Blocks");

    datablocks = nbt.getByteArray("Data");

    width = nbt.getShort("Width");

    length = nbt.getShort("Length");

    height = nbt.getShort("Height");

    sizes = new short[] { width, length, height };

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

     

    public void generate(World world, int posX, int posY, int posZ, boolean spawnairblocks) {

    try {

    int xnum = 0;

    int ynum = 0;

    int znum = 0;

     

    for (int i = 0; i < blocks.length; i++) {

    int blockId = UnsignedBytes.toInt(blocks);

    if (((blocks != 0) && (!spawnairblocks)) || (spawnairblocks == true)) {

     

    world.setBlock(posX + xnum, posY + ynum, posZ + znum, blockId, datablocks, 2);

    }

     

    if (xnum < width - 1) {

    xnum++;

    } else if ((xnum >= width - 1) && (znum < length - 1)) {

    xnum = 0;

    znum++;

    } else if ((xnum >= width - 1) && (znum >= length - 1) && (ynum < height - 1)) {

    xnum = 0;

    znum = 0;

    ynum++;

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    For reading old schematics, Block#getBlockById(int i) should work for reading them as blocks. In 1.7.10, I believe blocks still have metadata, so you should be good there, unless you are jumping straight from 1.6 to 1.8, in which case Block#getStateFromMeta will also be helpful.

  16. Ok, I have a Gui which renders fine when the window is small, but when the window is maximized/put in to fullscreen, it renders in the wrong spot.

     

    zofQm7b.pngJvO2LLr.png

     

    My setup is: the UtilityGui renders, then at the end of its render code, tells the overlay gui to render on top of it. Then, the foreground(just 1 item icon in the screenshots) renders over that. The foreground and UtilityGui render correctly, it is the overlay gui(GuiFireplaceCoreTab) that is in the wrong spot. Here is my code:

    GuiFireplaceCoreTab:

    https://bitbucket.org/The_Fireplace/fireplace-core/src/ae9361509a1bd65c5a09b5cdfaa1b7766a33b844/src/main/java/the_fireplace/fireplacecore/gui/GuiFireplaceCoreTab.java?at=master

    GuiModTab(superclass of GuiFireplaceCoreTab):

    https://bitbucket.org/The_Fireplace/fireplace-core/src/ae9361509a1bd65c5a09b5cdfaa1b7766a33b844/src/main/java/the_fireplace/fireplacecore/gui/GuiModTab.java?at=master

    UtilityGui(link to the line it makes GuiFireplaceCoreTab render):

    https://bitbucket.org/The_Fireplace/fireplace-core/src/ae9361509a1bd65c5a09b5cdfaa1b7766a33b844/src/main/java/the_fireplace/fireplacecore/gui/UtilityGui.java?at=master#cl-216

×
×
  • Create New...

Important Information

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