Jump to content

SnowyEgret

Members
  • Posts

    112
  • Joined

  • Last visited

Everything posted by SnowyEgret

  1. Seems we were replying at the same time. Will get back to you soon!
  2. I have answered the last part of my question. Instead of returning the model looked up in handleBlockState() I return this (which is an IBakedModel). This gives me the oportunity to modify or rebuild the BakedQuads list returned from getFaceQuads() and getGeneralQuads(): package ds.plato.block; import java.util.Arrays; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel; private IFlexibleBakedModel model; private IUnlistedProperty selectedBlockProperty; public BlockSelectedModel(IBakedModel defaultModel, PropertySelectedBlock selectedBlockProperty) { this.defaultModel = defaultModel; this.selectedBlockProperty = selectedBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(selectedBlockProperty); System.out.println("Selected block="+s); IBakedModel m = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(s); model = (IFlexibleBakedModel) m; return this; } @Override public List getFaceQuads(EnumFacing face) { List<BakedQuad> faceQuads = model.getFaceQuads(face); for (BakedQuad q : faceQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } //Modify list here return faceQuads; } @Override public List getGeneralQuads() { List<BakedQuad> generalQuads = model.getGeneralQuads(); System.out.println(Arrays.toString(generalQuads.toArray())); for (BakedQuad q : generalQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } //Modify list here return generalQuads; } @Override public boolean isAmbientOcclusion() { return model.isAmbientOcclusion(); } @Override public boolean isGui3d() { return model.isGui3d(); } @Override public boolean isBuiltInRenderer() { return model.isBuiltInRenderer(); } @Override public TextureAtlasSprite getTexture() { // return defaultModel.getTexture(); return model.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { return model.getItemCameraTransforms(); } } This runs fine. My questions are: Why does BakedQuad.getVertexData() return ints, and what do they mean? The vertex data seems to be the same for every model looked up in handleBlockState(): [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:35]: Selected block=minecraft:sand[variant=sand] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 0, 1065353216, -8421505, 1058537800, 1046480159, 0, 0, 0, 0, -8421505, 1058537800, 1048574689, 0, 1065353216, 0, 0, -8421505, 1059061432, 1048574689, 0, 1065353216, 0, 1065353216, -8421505, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -1, 1058537800, 1046480159, 0, 0, 1065353216, 1065353216, -1, 1058537800, 1048574689, 0, 1065353216, 1065353216, 1065353216, -1, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -1, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 0, -3355444, 1058537800, 1046480159, 0, 1065353216, 0, 0, -3355444, 1058537800, 1048574689, 0, 0, 0, 0, -3355444, 1059061432, 1048574689, 0, 0, 1065353216, 0, -3355444, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 1065353216, -3355444, 1058537800, 1046480159, 0, 0, 0, 1065353216, -3355444, 1058537800, 1048574689, 0, 1065353216, 0, 1065353216, -3355444, 1059061432, 1048574689, 0, 1065353216, 1065353216, 1065353216, -3355444, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -6710887, 1058537800, 1046480159, 0, 0, 0, 0, -6710887, 1058537800, 1048574689, 0, 0, 0, 1065353216, -6710887, 1059061432, 1048574689, 0, 0, 1065353216, 1065353216, -6710887, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 1065353216, -6710887, 1058537800, 1046480159, 0, 1065353216, 0, 1065353216, -6710887, 1058537800, 1048574689, 0, 1065353216, 0, 0, -6710887, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -6710887, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getGeneralQuads:55]: [] {ds.plato.block.PropertySelectedBlock@15af3a9b=Optional.of(minecraft:dirt[snowy=false,variant=dirt])} [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:35]: Selected block=minecraft:dirt[snowy=false,variant=dirt] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 0, 1065353216, -8421505, 1048576655, 1044383007, 0, 0, 0, 0, -8421505, 1048576655, 1046477537, 0, 1065353216, 0, 0, -8421505, 1049623921, 1046477537, 0, 1065353216, 0, 1065353216, -8421505, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -1, 1048576655, 1044383007, 0, 0, 1065353216, 1065353216, -1, 1048576655, 1046477537, 0, 1065353216, 1065353216, 1065353216, -1, 1049623921, 1046477537, 0, 1065353216, 1065353216, 0, -1, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 0, -3355444, 1048576655, 1044383007, 0, 1065353216, 0, 0, -3355444, 1048576655, 1046477537, 0, 0, 0, 0, -3355444, 1049623921, 1046477537, 0, 0, 1065353216, 0, -3355444, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 1065353216, -3355444, 1048576655, 1044383007, 0, 0, 0, 1065353216, -3355444, 1048576655, 1046477537, 0, 1065353216, 0, 1065353216, -3355444, 1049623921, 1046477537, 0, 1065353216, 1065353216, 1065353216, -3355444, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -6710887, 1048576655, 1044383007, 0, 0, 0, 0, -6710887, 1048576655, 1046477537, 0, 0, 0, 1065353216, -6710887, 1049623921, 1046477537, 0, 0, 1065353216, 1065353216, -6710887, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 1065353216, -6710887, 1048576655, 1044383007, 0, 1065353216, 0, 1065353216, -6710887, 1048576655, 1046477537, 0, 1065353216, 0, 0, -6710887, 1049623921, 1046477537, 0, 1065353216, 1065353216, 0, -6710887, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getGeneralQuads:55]: []
  3. Thanks TGG for the response. I think the last, more generic, method you proposed is the way I need to go. Just a few questions to begin. Here is a start for new handleBlockState(): @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(prevBlockProperty); IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes() .getModelForState(s); IFlexibleBakedModel m = (IFlexibleBakedModel) model; VertexFormat format = m.getFormat(); System.out.println("format=" + format); List<BakedQuad> generalQuads = m.getGeneralQuads(); System.out.println(Arrays.toString(generalQuads.toArray())); for (BakedQuad q : generalQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } for (EnumFacing face : EnumFacing.values()) { List<BakedQuad> faceQuads = m.getFaceQuads(face); for (BakedQuad q : faceQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } } return m; } When I run and select a vanila block sand, it appears to have no generalQuad data(the list of BakedQuads is empty), only faceQuad data. Can I assume that any model which has more than 6 standard sides will implement getGeneralQuads()? Here is the output of vertex data from the faceQuads: [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 0, 1065353216, -8421505, 1058537800, 1046480159, 0, 0, 0, 0, -8421505, 1058537800, 1048574689, 0, 1065353216, 0, 0, -8421505, 1059061432, 1048574689, 0, 1065353216, 0, 1065353216, -8421505, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -1, 1058537800, 1046480159, 0, 0, 1065353216, 1065353216, -1, 1058537800, 1048574689, 0, 1065353216, 1065353216, 1065353216, -1, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -1, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 0, -3355444, 1058537800, 1046480159, 0, 1065353216, 0, 0, -3355444, 1058537800, 1048574689, 0, 0, 0, 0, -3355444, 1059061432, 1048574689, 0, 0, 1065353216, 0, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 1065353216, -3355444, 1058537800, 1046480159, 0, 0, 0, 1065353216, -3355444, 1058537800, 1048574689, 0, 1065353216, 0, 1065353216, -3355444, 1059061432, 1048574689, 0, 1065353216, 1065353216, 1065353216, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -6710887, 1058537800, 1046480159, 0, 0, 0, 0, -6710887, 1058537800, 1048574689, 0, 0, 0, 1065353216, -6710887, 1059061432, 1048574689, 0, 0, 1065353216, 1065353216, -6710887, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 1065353216, -6710887, 1058537800, 1046480159, 0, 1065353216, 0, 1065353216, -6710887, 1058537800, 1048574689, 0, 1065353216, 0, 0, -6710887, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -6710887, 1059061432, 1046480159, 0] Do I use the format from VertexFormat format = m.getFormat() to interpret these arrays of ints? Also, there is no setQuads() method on IFlexibleBakedModel. Is this going to be a problem?
  4. Hi, I have implemented ISmartModel as instructed in TheGreyGhost's MBE04 tutorial. Things are working fine. In handleBlockState() I am looking up a model from an IBlockState I get from an unlisted property of the incoming IExtendedBlockState. Before returning the model, can I manipulate it? I am attempting to find a way to modify the color of it's texture (I posted a couple of days ago on this). There is a method returning the model's texture (of class TextureAtlasSprite), and a method to get the texture's texture data which is also setable. My printlns seem to indicate the texture data is changed, but I am not seeing any difference to the texture in game. Here is my implentation of ISmartModel: package ds.plato.block; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel; private IUnlistedProperty prevBlockProperty; public BlockSelectedModel(IBakedModel defaultModel, PropertyPreviousBlock prevBlockProperty) { super(); this.defaultModel = defaultModel; this.prevBlockProperty = prevBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(prevBlockProperty); IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes() .getModelForState(s); IFlexibleBakedModel m = (IFlexibleBakedModel)model; TextureAtlasSprite t = m.getTexture(); int[][] td = t.getFrameTextureData(0); System.out.println(Arrays.deepToString(td)); td = modifyTextureData(td); List l = new ArrayList(); l.add(td); t.setFramesTextureData(l); t = m.getTexture(); td = t.getFrameTextureData(0); System.out.println(Arrays.deepToString(td)); return m; } @Override public List getFaceQuads(EnumFacing p_177551_1_) { // TODO Auto-generated method stub return null; } @Override public List getGeneralQuads() { // TODO Auto-generated method stub return null; } @Override public boolean isAmbientOcclusion() { // TODO Auto-generated method stub return false; } @Override public boolean isGui3d() { // TODO Auto-generated method stub return false; } @Override public boolean isBuiltInRenderer() { // TODO Auto-generated method stub return false; } @Override public TextureAtlasSprite getTexture() { return defaultModel.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { // TODO Auto-generated method stub return null; } // Private------------------------------------------------------------- private int[][] modifyTextureData(int[][] data) { for (int i = 0; i < data.length; i++) { for (int j = 0; j < data[i].length; j++) { data[i][j] = 0; } } return data; } } For testing purposes I am just setting the texture data to 0. Seems I can cast the IBakedModel to an IFlexibleBakedModel, for whatever that's worth.
  5. Thanks for the suggestions. It is a specific list of blocks that I want to highlight, not everything around me.
  6. I would like to change the hue of one or more nearby blocks. I do not mean my block, but vanilla blocks, or other mod blocks. I would like to leave the form and texture intact, but modify the hue, for example, make it more red. I also mean a temporary, in game change, not a resource pack edit. Something like an translucent overlay for a list of blocks. How would you do this in 1.8?
  7. OK, got it. Thanks for your time.
  8. They can. Even better if they are. It hadn't occurred to me that an item had a stack in a creative tab. So how do I get a reference to the stack? There is no stack parameter in getSubItems.
  9. I have an item with an inventory written to it's item stack (like your ItemInventory class). More specifically, a staff with spells. In survival mode, a player crafts the staff, crafts the spells, then assembles the spells on the staff with a gui. In creative mode, I would like a player to be able to select a staff from his creative tab with spells already on it. When the staff is moved to the hotbar, it will write spells to it's item stack.
  10. To clarify, yes I mean when an item is moved from a creative tab to the hotbar/survival inventory. I can not see how getSubItems helps me. All I can come up with is overriding onUpdate, flagging the first time through, and ignoring subsequent calls.
  11. I would like to write to an item stack's tag as soon as an item is placed in a player's inventory. In survival, Item.on created is called after the item is crafted, which works fine. How can I do the same in creative?
  12. In my case, I am implementing IItemRenderer, so I don't have this.bindTexture(). Here is my IItemRenderer.renderItem(). How (and where) can I bind the texture? @Override public void renderItem(ItemRenderType type, ItemStack stack, Object... data) { GL11.glPushMatrix(); model.renderAll(); GL11.glPopMatrix(); }
  13. After struggling with similar problems on this thread http://www.minecraftforge.net/forum/index.php/topic,22360.msg114869.html#msg114869, it was pointed out to me that the gui should be opened on the server side only: if (!world.isRemote) { player.openGui(ChargeCore.instance, 0, world, x, y, z); return true; } If you put printlns in your two gui handler methods, you can see what effect this has on how they are called. The suggestion by MultiMote to use InventoryBasic will reduce the amount of code you are writing and help pinpoint the problem. Give your tile entity an InventoryBasic instead of implementing IInventory: public class BaseGeneratorTileEntity extends TileEntity { IInventory inventory = new InventoryBasic("BaseGenerator", false, 9);
  14. Exporting the uv layout creates a .png Exporting the model creates a .obj If the model is loaded like this: AdvancedModelLoader.loadModel(new ResourceLocation("myId", "models/model.obj")); what do I do with the .png?
  15. Finally! It works. Thank you diesieben07. Here is my implementation of IInventory based on ItemInventory.WithInventory. It's a little different in that it writes to the tag at every call to setInventorySlotContents and does not maintain an ItemStack arrray. Note second line of setInventorySlotContents(); public class MyInventory implements IInventory { // This wrapper encapsulates the complexities of writing to the tag private MyTagWrapper tag; private int size = 9; IInventory inventory; ItemStack stack; private int slot; public MyInventory(IInventory inventory, int slot) { this.inventory = inventory; this.slot = slot; this.stack = inventory.getStackInSlot(slot); NBTTagCompound t = stack.getTagCompound(); if (t == null) { t = new NBTTagCompound(); stack.setTagCompound(t); } tag = new MyTagWrapper(t, size); } @Override public ItemStack getStackInSlot(int i) { return tag.getItemStack(i); } //Stack limit is 1 @Override public ItemStack decrStackSize(int i, int amount) { ItemStack stack = tag.getItemStack(i); tag.setItemStack(i, null); return stack; } @Override public ItemStack getStackInSlotOnClosing(int i) { if (tag.getItemStack(i) != null) { ItemStack itemstack = tag.getItemStack(i); tag.setItemStack(i, null); return itemstack; } else { return null; } } @Override public void setInventorySlotContents(int i, ItemStack stack) { tag.setItemStack(i, stack); //This is what was missing previously inventory.setInventorySlotContents(slot, this.stack); } @Override public int getSizeInventory() { return size; } @Override public String getInventoryName() { return null; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 1; } @Override public void markDirty() { } @Override public boolean isUseableByPlayer(EntityPlayer p_70300_1_) { return true; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int i, ItemStack stack) { return true; } } Here is where it is constructed: public class MyGuiHandler implements IGuiHandler { @Override public Object getServerGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { return new MyContainer(player.inventory, new MyInventory(player.inventory, player.inventory.currentItem)); } @Override public Object getClientGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { return new MyGui(new MyContainer(player.inventory, new MyInventory(player.inventory, player.inventory.currentItem))); } }
  16. From you javadoc: >If the ItemStack being written to is in an inventory itself, {@link ItemInventory.WithInventory} should be used instead. Just to be sure I understand, do you mean "if the ItemStack being written to is referenced by another inventory", or maybe "if you have already constructed an instance of ItemInventory with this ItemStack"? If so, does this apply to my case? Would I use it something like this: public class MyGuiHandler implements IGuiHandler { IInventory inv; @Override public Object getServerGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { inv = new ItemInventory(player.getCurrentEquippedItem()); return new MyContainer(player.inventory, inv); } @Override public Object getClientGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { int slot = ?; return new MyGui(new MyContainer(player.inventory, new ItemInventory.WithInventory(inv, slot))); } } I'm lost .
  17. Yes, much better. I am no longer getting strange behaviour in my container. Before I was passing the same inventory object to both client and server sides. Thank you. I still have one problem. I am writing to the tag but I seem to be getting a new empty tag object from getCurrentEquippedItem() every time I reopen the gui. Should the gui be opened from the client side, the server side, or both in onItemUse()? If I open only from the server, getServerGuiElement() and getClientGuiElement() are called each once: @Override public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int s, float sx, float sy, float sz) { if (!world.isRemote) { player.openGui(MyMod.instance, 0, world, x, y, z); return true; } return false; } public class MyGuiHandler implements IGuiHandler { @Override public Object getServerGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { NBTTagCompound t = player.getCurrentEquippedItem().getTagCompound(); System.out.println("[MyGuiHandler.getServerGuiElement] w=" + w + ", tag=@" + System.identityHashCode(t) + t); return new MyContainer(player.inventory, new MyInventory(player.getCurrentEquippedItem())); } @Override public Object getClientGuiElement(int id, EntityPlayer player, World w, int x, int y, int z) { NBTTagCompound t = player.getCurrentEquippedItem().getTagCompound(); System.out.println("[MyGuiHandler.getClientGuiElement] w=" + w + ", tag=@" + System.identityHashCode(t) + t); return new MyGui(new MyContainer(player.inventory, new MyInventory(player.getCurrentEquippedItem()))); } } Console (opening gui twice): [MyGuiHandler.getServerGuiElement] w=net.minecraft.world.WorldServer@6c0486cc, tag=@421020847{} [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@506382b1, tag=@317245315{} [MyGuiHandler.getServerGuiElement] w=net.minecraft.world.WorldServer@6c0486cc, tag=@821869132{} [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@506382b1, tag=@539684020{} I seem to be getting a different tag object each time. Opening the gui from both sides gives: [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@9da1db, tag=@1217657581{} [MyGuiHandler.getServerGuiElement] w=net.minecraft.world.WorldServer@1693401c, tag=@1166845275{} [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@9da1db, tag=@1217657581{} [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@9da1db, tag=@824254376{} [MyGuiHandler.getServerGuiElement] w=net.minecraft.world.WorldServer@1693401c, tag=@1973774282{} [MyGuiHandler.getClientGuiElement] w=net.minecraft.client.multiplayer.WorldClient@9da1db, tag=@824254376{}
  18. 07, I had a look at SevenCommons. If I understand, you would pass an itemStack maybe to the gui handller so that it can construct a new inventory and then the container every time the gui is opened? Something like: @Override public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int s, float sx, float sy, float sz) { MyMod.instance.guiHandler.setItemStack(stack); player.openGui(MyMod.instance, 0, world, x, y, z); return true; } public class MyGuiHandler implements IGuiHandler { IInventory inventory; public void setItemStack(ItemStack stack) { inventory = new ItemInventory(stack); } @Override public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { return new MyContainer(player.inventory, inventory); } @Override public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { return new MyGui(new MyContainer(player.inventory, inventory)); } }
  19. Thanks again for your reply. >You would have your item (possibly implement IInventory and) use the ItemStack to load the slots This is all clear to me. In my case, I have given my item a field named inventory which implements IInventory. This is the inventory that I pass to my container and my gui, and this inventory writes to ItemStack.stackTagCompound. My question is how to pass the stack to the inventory? IIventory has a getter and a setter which is called by the container: ItemStack getStackInSlot(int p_70301_1_); void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_); neither of which include a parameter of type ItemStack which I can get the tag from. (The stack in setInventorySlotContents is what I am putting in the slot). Items don't know what stack they are in - they have to be told. In methods like Item.onItemUse() pass the stack as a parameter for this reason. As a workaround, I am passing the stack (actually just the tag) to the inventory with my own method MyInventory.setTag(NBTTagCompound tag) when the gui is opened. The problem is that this sets a field in MyInventory which, because there is only one instance of the item in the game, will be shared between players, and we are back at square one. It's only a minor problem because the players would have to open the containers at the same time for there to be a conflict. Thanks also for the suggestion of looking at the backpack mod, which is on GitHub. There are thousands of lines of code there. I will try to slug my way though it
  20. Hi again Ewe, Searching my workspace gives: From net.minecraftforge.oredict.RecipeSorter: @Override public int compare(IRecipe r1, IRecipe r2) { Category c1 = getCategory(r1); Category c2 = getCategory(r2); if (c1 == SHAPELESS && c2 == SHAPED) return 1; if (c1 == SHAPED && c2 == SHAPELESS) return -1; if (r2.getRecipeSize() < r1.getRecipeSize()) return -1; if (r2.getRecipeSize() > r1.getRecipeSize()) return 1; return getPriority(r2) - getPriority(r1); // high priority value first! } and net.minecraft.item.crafting.CraftingManager: public int compare(IRecipe p_compare_1_, IRecipe p_compare_2_) { return p_compare_1_ instanceof ShapelessRecipes && p_compare_2_ instanceof ShapedRecipes ? 1 : (p_compare_2_ instanceof ShapelessRecipes && p_compare_1_ instanceof ShapedRecipes ? -1 : (p_compare_2_.getRecipeSize() < p_compare_1_.getRecipeSize() ? -1 : (p_compare_2_.getRecipeSize() > p_compare_1_.getRecipeSize() ? 1 : 0))); }
  21. Ewe, >or do all stacks of the item to share the same inventory? Ideally, each item has its own inventory. I've given MyItem an instance of MyInventory implementing IInventory instead of extending InventoryBasic. To read and write to the tag I need MyItem's stack. How can I get the stack when it is not passed to IInventory.getStackInSlot(int) and IInventory.setInventorySlotContents(int, ItemStack)? So far, I am passing the stack to MyInventory when MyItem's gui is opened, but this will not work when two players modify the inventory at the same time. >you should not be changing the inventory on the client, you should only change it on the server I am not sure where to do this. In the gui handler?, testing for world.isRemote when opening the gui? do I override something in Container? in my implementation of IInventory? Here is MyInventory (inventory stack limit is 1, so decrStackSize is simplified. MyTagWrapper will read and write the tag) : public class MyInventory implements IInventory { private MyTagWrapper tag; private String name; private boolean hasName; public MyInventory(int size) { tag = new MyTagWrapper(9); } public void setItemStack(ItemStack stack) { tag.setTag(stack.getTagCompound()); } ////// Implementation of IInventory @Override public ItemStack getStackInSlot(int i) { if (i < 0 || i > tag.getSize() - 1) { throw new IllegalArgumentException("Not in tag range: " + i); } return tag.getItemStack(i); } @Override public ItemStack decrStackSize(int i, int amount) { ItemStack stack = tag.getItemStack(i); tag.setItemStack(i, null); return stack; } @Override public ItemStack getStackInSlotOnClosing(int i) { if (tag.getItemStack(i) != null) { ItemStack itemstack = tag.getItemStack(i); tag.setItemStack(i, null); return itemstack; } else { return null; } } @Override public void setInventorySlotContents(int i, ItemStack stack) { if (i < 0 || i > tag.getSize() - 1) { throw new IllegalArgumentException("Not in tag range: " + i); } tag.setItemStack(i, stack); markDirty(); } @Override public int getSizeInventory() { return tag.getSize(); } @Override public String getInventoryName() { return name; } @Override public boolean hasCustomInventoryName() { return hasName; } @Override public int getInventoryStackLimit() { return 1; } @Override public void markDirty() { } @Override public boolean isUseableByPlayer(EntityPlayer p_70300_1_) { return true; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int i, ItemStack stack) { return true; } }
  22. The safest (and easiest) way to override a method in Eclipse is to right click on the window background and choose Source>Override/Implement Methods... You can check to method(s) you want, then click Ok. This way you ensure the signatures are correct and the @Override notation is included. If you are not sure if you have all your @Override notations, choose Source>Clean Up...
  23. You have set field mirror on Right_Fin before you initialize it on the next line, so, Right_Fin is null. Right_Fin.mirror = true; Right_Fin = new ModelRenderer(this, 0, 0); If you are running from inside Eclipse (and you should be during development) exceptions and their stacktraces are printed to the console window. The file name and line number of each call are links that are hightlighted in red and underlined. You can click on the link and it will bring you directly to the line in the file where the call was made. In your case, clicking on Fish.java:45 will open Fish.java with the line Right_Fin.mirror = true; highlighted. There is only one thing that can be null here. Incidentally, does Techne really generate uppercase variable names?
  24. java.lang.NullPointerException: Rendering item at net.minecraft.item.ItemStack.getItemDamage(ItemStack.java:267) Line 267 of ItemStack looks like: public int getItemDamage() { return getItem().getDamage(this); } So, you have an ItemStack with a null item. My guess is your class BlockManager is returning null when one (or all) of its fields are being referenced: GameRegistry.addShapedRecipe(new ItemStack(BlockManager.amythestBlock), "xxx", "xxx", "xxx", 'x', ItemManager.amethyst); GameRegistry.addShapedRecipe(new ItemStack(BlockManager.blueTopazBlock), "xxx", "xxx", "xxx", 'x', ItemManager.blueTopaz); GameRegistry.addShapedRecipe(new ItemStack(BlockManager.carnelianBlock), "xxx", "xxx", "xxx", 'x', ItemManager.carnelian); GameRegistry.addShapedRecipe(new ItemStack(BlockManager.peridotBlock), "xxx", "xxx", "xxx", 'x', ItemManager.peridot); GameRegistry.addShapedRecipe(new ItemStack(BlockManager.roseQuartzBlock), "xxx", "xxx", "xxx", 'x', ItemManager.roseQuartz);
  25. The first line of your stack trace says you are calling a method on a null object in the constructor of your class Fish, on line 45. java.lang.NullPointerException: Initializing game at com.extraores.model.Fish.<init>(Fish.java:45) Your problem is not in class RenderMyFishMob. Go to line 45 of class Fish and look for an object you are calling a method on. For some reason, it is null.
×
×
  • Create New...

Important Information

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