Jump to content

Pancake

Members
  • Posts

    43
  • Joined

  • Last visited

Everything posted by Pancake

  1. As mister pickaxe pointed out, is the method registerItems() in ItemsMO called? Put a println in there if you're not sure, and see if it prints something.
  2. I'm confused. is this supposed to help me? Don't I already have this part? I showed it in my original post.
  3. I've narrowed the problem further down, the Block.getIdFromBlock(my_block) returns -1. It isn't properly registered, somehow. Yet I feel like I'm pretty sure It's registered... Am I supposed to do something extra? my mod worked fine untill now
  4. Greetings! In my code I recently added some recipes for items (I was on creative the whole time, so I didn't need them) and my recipe-loader fails to work with blocks of my mod. I've narrowed down where the issue is: the .getItem() method on an itemstack of a custom block returns null. Does my block class need to extend ItemBlock? Then how do I give it a TileEntity? (it's currently extending BlockContainer) I've read through the getItem method of ItemStack, and saw it checks if a delegate is null or not. It gets initialised when you construct an ItemStack with an Item, but I'm registering it with a Block... Which shouldn't be a problem right? This is the relevant code for the block and recipe registry: public static Block BlockItemStorageUnitTier1 = new BlockItemStorageUnitTier1(); public static Block BlockItemStorageUnitTier2 = new BlockItemStorageUnitTier2(); public static Item ItemMechanicalBindingComponent = new ItemMechanicalBindingComponent(); @EventHandler public void preInit(FMLInitializationEvent event){ GameRegistry.registerBlock(BlockItemStorageUnitTier1,"BlockItemStorageUnitTier1"); GameRegistry.registerBlock(BlockItemStorageUnitTier2,"BlockItemStorageUnitTier2"); GameRegistry.registerTileEntity(TileEntityItemStorageUnitTier1.class,"TileEntityItemStorageUnitTier1"); GameRegistry.registerTileEntity(TileEntityItemStorageUnitTier2.class,"TileEntityItemStorageUnitTier2"); GameRegistry.registerItem(ItemMechanicalBindingComponent,"ItemMechanicalBindingComponent"); } @EventHandler public void init(FMLInitializationEvent event){ ItemStack stackSUT1 = new ItemStack(BlockItemStorageUnitTier1); ItemStack stackSUT2 = new ItemStack(BlockItemStorageUnitTier2); ItemStack stackMBC = new ItemStack(ItemMechanicalBindingComponent); GameRegistry.addShapedRecipe(stackSUT2,"xxx","xyx","xxx",'x',stackSUT1,'y',stackMBC); System.out.println(stackSUT1); } /code] That crashes on the println, because the toString() method of an ItemStack asks item.getUnlocalizedName(), and item is null. I have no idea what to do. I need the item object to not be null for my crafting system. How else can I get an object from an itemstack that's shared amongst multiple itemstacks of the same kind? Thanks in advance, Pancake
  5. Thanks for the quick response!
  6. Greetings! There seems to be something strange going on with the OreDictionary name for planks: plankWood. If you request all ItemStacks for that name, you get an ArrayList with only one element: Oak Wood Planks. What happened to the rest of the planks? Are they handled differently than other OreDictionary things? Does vanilla take care of them and am I supposed to make an exception for them? This is the code used: ArrayList<ItemStack> list = OreDictionary.getOres("plankWood"); System.out.println("list size: "+list.size()); for(ItemStack stack : list){ System.out.println(stack.getDisplayName()); } Which produces the following output... list size: 1 Oak Wood Planks Some back info: I came upon this issue because the autocrafting system I made wouldn't use birch planks for crafting a chest. Thanks in advance, Pancake.
  7. I might've found a work-around. It's amazing how writing everything down, and trying to formulate things for another person orders your thoughts for yourself, allowing you to think outside the pattern that you've been in for hours. So, when getting that arraylist, it contains all possible itemstacks that fit there, right? I take the first stack, get all the oredictionary ids for that stack (int[]). For each id, I get oreDictionary.getOres(id), which is what the OreRecipe classes get and put in their fields. I then check if that arraylist is equal to the original arraylist. Exactly one of the ids should produce the exact same ArrayList ('exact' is a big word, it's a different object), and that id is the one filled in in the constructor. I rest my case. It would still be nice if the OreRecipes would save the OreDictionary strings as fields though. It'd be faster that way. But hey. 10 milliseconds for all the ShapedOreRecipes isn't bad... And it should only run once anyways.
  8. Greetings! If you don't like reading, read my question at the bottom (bold). If you don't know what I'm talking about, read the text. I want to make an autocrafting system. I can currently load ShapedRecipes and ShapelessRecipes correctly into an Object that will be generated once at the initialisation. (although the code is now in a onBlockActivated method, for testing) I have an issue regarding OreRecipes though. I'd link to link (HashMap) every output (ItemStack) to a collection (HashSet) of possible outputs (HashMap) where every ingredient (ItemStack) is linked to the amount you need (Integer). The complete type of this Object is HashMap<ItemStack,HashSet<HashMap<ItemStack,Integer>>>. It looks complicated, but it contains everything I'll need. I use this for ShapedRecipes and ShapelessRecipes. The ShapedOreRecipe and ShapelessOreRecipe are a different story... For those I'll replace the HashMap<ItemStack,Integer> by a HashMap<Object,Integer> where the Object can be an ItemStack (normal, non OreDictionary item) or an Integer (the OreDictionary ID). My problem lies within getting that ID. I'll explain how data is retrieved from OreRecipes for those who want to try it themselves. A ShapedOreRecipe gives you, just like the ShapedRecipe, an array of size 9, but it isn't an ItemStack array, it's an Object array. It can contain null (no item), an ItemStack (just a normal item with no OreRegistry ID mapped to it) or an ArrayList (a special kind of ArrayList, but whatever). If it's an ArrayList, It will contain all possible ItemStacks for that slot. You can ask the OreDictionary IDs (it can have multiple) of an ItemStack, it gives you integer array (int[]). I get those arrays of all the items in the arraylist, and check which value(s) are common between all items. Now for, my problem... Let's suppose someone made a recipe that combines any 2 metals, and gives a mixed metal ingot. there are 2 metals in game: "oreCopper" and "oreTin" and they are both also registered as "oreMetal". The valid items for slot 1 would be "oreCopper" AND "oreTin". I try to get the common ore ID, and get the number associated with "oreMetal" (it's the common between an itemstack of copper and tin). Now we try to paint wool red. for slot 1 you get a common name of "cloth" or something like that. for slot 2, there's only 1 option: rose red. what are the common ore names for that 1 item? "dye" and "dyeRed". there's no way to check which is the more 'specific' one, because there's only 1 item. If you understood all of that, and comprehend where the problem lies, congratulations to you. And to me, for explain so well If not... i'm sorry. feel free to ask questions. Now for my core question: is it possible to, instead of an arraylist of all the possible blocks that fit in that slot, get the OreDictionary name/ID for that slot? Is there anyway to get the name used in the constructor of an OreRecipe? (they require them) Thanks in advance, Pancake. PS: If an admin/moderator storms in, blurts out an answer without reading and closes this thread, I reserve the right for myself to copy-paste this wall of text, and recreate an exact copy of this thread. #nohate
  9. Nothing a try-catch won't fix.
  10. I suppose you COULD get itemstacks that way... Just one remark. What if multiple ores use the same block ID but different metadata? Doesn't the constructor ItemStack(Item) auto-set the metadata to 0? Just saying... But as long as each modder defines different ores as different blocks, you'll be fine! (and me too, i'm stealing your code! muahaha!)
  11. +1. I've been looking for this for 2 hours now, and was about the same question on this forum as well. What a coincidence. Don't worry, I need it for other uses than you. I need to be able to get an ItemStack out of the IRecipe.getInput(). It returns an array of Objects. If I try to cast the first element of the array to an ArrayList type, it says "net.minecraft.item.ItemStack cannot be cast to java.util.ArrayList". if I try to cast it to an ItemStack, it says "net.minecraftforge.oredict.OreDictionary$UnmodifiableArrayList cannot be cast to net.minecraft.item.ItemStack" I'm confused. How should I cast the Object to something that I can use? The class UnmodifiableArrayList cannot be found. Thanks in advance, Pancake.
  12. Greetings! some quick questions, regarding efficiency. 1) I try to get a list of all the items. Is this an efficient way? GameData.getItemRegistry().getKeys() 2) for each String s in that set, I do [1] to get an Item Object. To get the display name (not the unlocalised name, I want the name it shows the user, is it necessary to make a new ItemStack with that item, and do [2] or can it be retrieved from the item directly? I couldn't find anything in the Item class. [1] GameData.getItemRegistry().getObject(s) [2] stack.getDisplayName() That's all for now. I might edit this post and bump this thread if I have more relatively easy problems. Thanks in advance, Pancake. EDIT: about (2) ... I just remembered Items can have metadata, and one metadata of an item can have a different name than another metadata. I'll just make the list of items based on the output of all the recipes. Thanks anyways... for reading and silently judging me.
  13. Buildcraft did that in it's code, because it requests those integers in the class that implements LoadingCallback, to get the TileEntity, upon which it calls the function forceChunkLoading(). It stores the ticket in the TileEntity, so it doesn't make a new one. Check my code in the TileEntity in the method updateEntity to see why I need the ticket in the TileEntity. I couldn't get the worldObj in the constructor, so I had to get it somewhere else. The first time the method runs, the game hasn't tried to make a ticket yet, so it tries. if it isn't null, then it means it was already loaded upon entering the world, and there's no need for it to make a new one. See why I need the ticket in the TileEntity? :3 If there's an easier way, do tell me, because I figured this all out from someone else's code, I might be doing alot of unnecessary steps. EDITEDITEDIT: Omg. I just saw my mistake. I copied something, and didn't bother to change the X to Y and Z... My bad!
  14. Well, after watching at the source code for the buildcraft quarry block and the corresponding tile entity, I fixed my errors. I requested a ticket before my mod was registered, and I registered my mod everytime a new TileEntity was created. I created a new class which implements OrderedLoadingCallback, and I implemented the two ticketsLoaded methods. I added the following code to my main mod class. And this is now my TileEntity. (I left out the other methods which don't have to do anything with this solution) Now my chunk stays loaded on the serverside. I'm pretty happy with this solution, and i'm glad I could share it with those that don't have the patience I've had for the last two days. I had to request a ticket in the updateEntity method, because the worldObj is still null when constructing the TileEntity object, and you need it to request a ticket. EDIT: fixed 2 mistakes in my code. Thanks Draco. :3
  15. ~ Decided to bump, since i tried more stuff, and I think i'm getting close... for the fourth time. ~ All of the thigns below here are graciously copied and distilled from the code for a buildcraft quarry. I added the following lines of code to my constructor of my TileEntity (TileEntityMainframeUnit) which extends TileEntity and implements LoadingCallback ticket = ForgeChunkManager.requestTicket(Singularity.instance,worldObj,Type.NORMAL); ticket.getModData().setInteger("locationX",xCoord); ticket.getModData().setInteger("locationY",yCoord); ticket.getModData().setInteger("locationZ",zCoord); ForgeChunkManager.forceChunk(ticket,new ChunkCoordIntPair(xCoord>>4,zCoord>>4)); ForgeChunkManager.setForcedChunkLoadingCallback(Singularity.instance,this); ticket is a private field. I have overriden the following method @Override public void ticketsLoaded(List<Ticket> tickets, World world) { for(Ticket t : tickets){ int locationX = ticket.getModData().getInteger("locationX"); int locationY = ticket.getModData().getInteger("locationY"); int locationZ = ticket.getModData().getInteger("locationZ"); TileEntityMainframeCore entity = (TileEntityMainframeCore)world.getTileEntity(locationX, locationY, locationZ); entity.forceChunkLoading(ticket); } } where the method forceChunkLoading is the following: public void forceChunkLoading(Ticket ticket) { if (this.ticket == null) { this.ticket = ticket; } ChunkCoordIntPair chunk = new ChunkCoordIntPair(xCoord >> 4, zCoord >> 4); ForgeChunkManager.forceChunk(ticket,chunk); } i'm getting the following error upon placing a BlockMainFrame(which has a TileEntityMainFrame): The mod Singularity has attempted to request a ticket without a listener in place Doesn't refferencing my mod instance take care of the listeners? I must be confused... Thanks in advance, Pancake.
  16. I know, this problem has come up plenty of times on this forum, but I've read almost all of the threads about it here and on external forums, and I've looked into several source codes from other mods. Nothing helped me to make implement it into my own mod. The problem is this: I'm trying to access a TileEntity somewhere in the world. That TileEntity CAN be far away, outside of player-loaded chunks. So I've been thinking, and my only solution is to make the block a chunkloader. All the other threads about this subject I've read either tell me to: - go check source code for ChickenChunks (which is too complicated to be able to ... the elements I need for a simple chunkloader) OR - try to explain the code, giving single lines which aren't helping because I have no idea where to put them. (In the mod main class? in the block class? in the TileEntity? A new class?) I know Java, so reading/writing code isn't the problem. It's the fact that I don't have a complete overview of whatever Forge is doing in the background that messes me up. So what I'd like is a person who can give me an overview of what classes I need to implement/extend in what classes, and what methods should be implemented/overriden and what should be in them to be able to keep a chunk loaded while the game is running. Ofcourse, what needs to be in the methods can be in pseudo-code, I'll understand. Thanks in advance, Pancake :3
×
×
  • Create New...

Important Information

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