Jump to content

SuperGeniusZeb

Forge Modder
  • Posts

    70
  • Joined

  • Last visited

Everything posted by SuperGeniusZeb

  1. If I had to guess, I'd say the problem originates at line 24 in MineBoardBlocks.java: GameRegistry.register(cardboard_block.setRegistryName("cardboard_block")); Maybe this is a 1.9 thing (I'm currently using 1.8.9) but don't you need to set an ItemBlock when you register any block? In 1.8.9 the line would be something like: GameRegistry.registerBlock(cardboard_block, ItemBlockCardboard.class, "cardboard_block"); I'm actually updating my mod to 1.9 right now so I'll go see how it works in that version, but I think this might be why you're getting errors with the block but not the items.
  2. I have now updated the mod to 1.8.9, and I've added slabs as well! A lot has changed behind-the-scenes in the code to make it more efficient and easier to add new blocks, and I've learned quite a bit about how Minecraft & Forge works while coding this update, so expect the next update to come sooner! The mod will be ported to 1.9 and 1.9.4 soon, and I'm planning for the next update, 1.2, to have stairs, fences, walls, transparent blocks, transparent slabs, transparent stairs, transparent panes, bows, shields, and tools/armor rebalancing for 1.9. New 1.1 Release Trailer: Future Updates & Additional Info:
  3. ...And, 2 months later, after a lot of time being busy and being unable to work on my mod, I have recently been able to get my slabs working! Yay! Vanilla does have similar classes... see BlockHalfStoneSlab and BlockDoubleStoneSlab. Thanks for the suggestion! After looking around in the ItemSlab class I was able to figure out how to get the half-slabs and double-slabs to be associated with each other, and I also learned quite a bit about how the slabs and a lot of other Minecraft code works in the process. (Discovered ItemSlab's this.singleSlab, which I had to indirectly access the values by creating a private variable in my ItemBlockColoreSlab class which I assigned the value of this.singleSlab, and then created setter & getter methods so I could easily-ish convert between a double slab as input in a method to its single slab counterpart.) I also cleaned up and simplified a lot of my code (thanks for adding the getRegistryName() & findBlock() methods, Forge team) and have a much better (but still not yet perfect) understanding of the Minecraft/Forge code. For those who are having the same problem as me, I will update the main post with my new code, which I think would work as a better template for slabs with additional metadata/blockstates than the current 1.8 slabs tutorial on these forums. Note that I have renamed BlockRegistry.java & BlockRenderRegistry.java to ModBlocks.java & BlockRenders respectively, since those are more in line with the standard naming conventions and I think they make more sense than what I had before. I would like to note that I am not fully satisfied with how I handle getting the name of a double slab's single/half slab counterpart. (See my comments in the updated code.) It feels a little indirect & hacky to me, and if anyone has any suggestions for a better way, please let me know. I really want my code to be clean and not use hacky, indirect ways of getting things to work.
  4. UPDATE 5-8-2016: I have now figured out how to get my slabs working, and I have updated this post with the working code. The original post can be seen in the spoiler at the bottom. Thanks for the help, everyone! If you have any questions about certain parts of my code or suggestions on how to do it better let me know! Working Code for slabs with additional blockstates/metadata in Minecraft 1.8.9: Original Post:
  5. Bump again... anyone know what I need to change in order to get the slabs to work?
  6. Bump. Still need help... see main post for current situation...
  7. And... I'm stuck again. I've updated the main post with the changed code and the current state of how things are working. At least the game isn't crashing anymore.
  8. Wasn't a problem in my main class. Just me making more dumb mistakes. Before: public static BlockColoreSlabHalf slab_of_red; GameRegistry.registerBlock(slab_of_red = new BlockColoreSlabHalf("slab_of_red"), ItemBlockColoreSlab.class, slab_of_red, slab_of_red, slab_of_red_double, false); After: public static BlockColoreSlab slab_of_red = new BlockColoreSlabHalf("slab_of_red"); public static BlockColoreSlab slab_of_red_double = new BlockColoreSlabDouble("slab_of_red_double"); GameRegistry.registerBlock(slab_of_red = new BlockColoreSlabHalf("slab_of_red"), ItemBlockColoreSlab.class, "slab_of_red", slab_of_red, slab_of_red_double, false); Aside from inputing some wrong values in the registerBlock functions, I also forgot to give slab_of_red_double a value when I first initialized it, so when its name was called in slab_of_red's registerBlock parameters, it caused null pointer exceptions and stuff. I think there were also a couple of other errors, but they're fixed now. (I think.) The game will now launch without crashing, and you can place down the red slabs, which have no texture but work as half a block and function like a normal slab, except for turning into a double slab. They show up as null.normal.name in the creative menu, but I'm hoping that I can fix that easily. I think I can fix everything else from here, but if not, I'll update the main post with the updated code. Thanks for your help so far.
  9. Fixed. Will update main post with the new crash report I get and the changes I've made... EDIT: Also, @jeffryfisher: Thanks, I found the point at which the game crashes now that I fixed the aforementioned silly mistake... It crashes when I try to call registerBlock on one of the slabs. I know I've done something wrong there, but I'm not sure what exactly it is or how to fix it...
  10. UPDATED 2-9-2016: The game launches, and the slabs sort of work. At this point I haven't created any model,texture, or other .json files for any of the slabs, and neither have I put them in the .lang file. The half-slabs can be placed like regular slabs, and act normal, except that they can't be stacked. Both the regular and the double slabs show up in the creative tab I have created for them, though the double slabs shouldn't be there. Both the half and double variants of the slabs have the same name in the creative menu. (For example, the slab_of_red with a SHADE state of "NORMAL" shows as tile.slab_of_red.normal.name, and its double variant shows with the exact same name, but when viewed in F3+H mode, you can see their actual code names of colore:slab_of_red and colore:slab_of_red_double... I'm not sure if this is normal or not, as I have not tried to create any .json files or textures yet.) Using: Latest version of Forge for 1.8.9 and latest JDK 8. So I've been working on my first mod, Colore, which adds monochrome blocks and items and such. I was trying to implement slabs, but I've been having to stop coding for long periods of time only to come back and be lost, and none of the examples or tutorials I've found have really explained everything to me that well. I know how slabs work in game (they're 2 different blocks: a half-slab block with at least 2 blockstates and a double slab block that's basically just a normal block that drops 2 of the former) and that you're supposed to have an abstract slab class (BlockColoreSlab), a half slab class (BlockColoreSlabHalf), a double slab class (BlockColoreSlabDouble), and an item-block class (ItemBlockColoreSlab), but I have no idea how to get them working right. I have the metadata on the slabs set up with 2 properties: "SHADE" and "HALF". "SHADE" has 5 different values: normal, light, lighter, dark, and darker, and "HALF" has, of course, just 2 values and determines whether the block is a top slab of bottom slab (if it is even a half slab.) So for example I'm trying to add a Slab of Red that uses the metadata to determine both the color and which type of slab it is. (Values 0-4 are bottom slabs and 5-9 are top slabs. Double slabs just have values 0-4.) I don't have any prior experience in modding slabs in any version, and honestly, I feel like I'm starting to get lost in my own code now. Every tutorial/example I've seen seems to do things in an unusual or complicated way that is unnecessary for my purposes, and it's really hard to tell what I'm doing wrong. Anyway, here are the slab classes and the classes I use to register my blocks. If you need to see any more, just let me know. See the top of the post for the current state of how things are working. (I'll update it as I fix things and make progress...) BlockColoreSlab (abstract slab class): package com.supergeniuszeb.colore.common.blocks; import net.minecraft.block.Block; import net.minecraft.block.BlockSlab; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockPos; import net.minecraft.util.IStringSerializable; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.supergeniuszeb.colore.common.registry.CreativeTabRegistry; //An abstract class for both half-slabs and full/double slabs. public abstract class BlockColoreSlab extends BlockSlab implements IMetaBlockName{ public BlockColoreSlab(String unlocalizedName) { super(Material.rock); this.setHardness(1.5f); this.setHarvestLevel("pickaxe", 0); this.setResistance(10.0f); this.setUnlocalizedName(unlocalizedName); this.useNeighborBrightness = !this.isDouble(); if (!this.isDouble()) { this.setCreativeTab(CreativeTabRegistry.slabTab); } //Sets default state depending on whether block is a half-slab or double-slab. IBlockState blockState = this.blockState.getBaseState(); blockState = blockState.withProperty(SHADE, EnumShade.NORMAL); if (!this.isDouble()) { blockState = blockState.withProperty(HALF, EnumBlockHalf.BOTTOM); } this.setDefaultState(blockState); } public enum EnumShade implements IStringSerializable { NORMAL(0, "normal"), LIGHT(1, "light"), LIGHTER(2, "lighter"), DARK(3, "dark"), DARKER(4, "darker"); private int ID; private String name; private EnumShade(int ID, String name) { this.ID = ID; this.name = name; } @Override public String getName() { return name; } @Override public String toString() { return getName(); } public int getID() { return ID; } } //The shade ("light", "dark", etc.) of the slab. The "HALF" property is defined in the vanilla BlockSlab class so I don't need to make my own. public static final PropertyEnum SHADE = PropertyEnum.create("shade", BlockColoreSlab.EnumShade.class); //Function to get the variant property created above based on the item. @Override public final Object getVariant(final ItemStack itemstack) { return itemstack.getMetadata(); } //Function to get the variant property. @Override public final IProperty getVariantProperty() { return SHADE; } @SideOnly(Side.CLIENT) @Override public final net.minecraft.item.Item getItem( final net.minecraft.world.World world, final net.minecraft.util.BlockPos blockPos) { String blockId = this.getUnlocalizedName(); return Item.getItemFromBlock(Block.getBlockFromName(blockId)); } @Override protected BlockState createBlockState() { return new BlockState(this, new IProperty[] {SHADE, HALF}); } //Converts an IBlockState into metadata. @Override public IBlockState getStateFromMeta(int meta) { //A blockState is created, which is assigned the SHADE property depending on its metadata, as well as the HALF property, if it is a half-slab. IBlockState blockState = this.getDefaultState(); if (!this.isDouble()) { //If the block is a BlockColoreHalfSlab switch (meta) { case 0: blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM); break; //Note-to-self: NEVER EVER FORGET TO USE THIS IF RETURN STATEMENTS AREN'T INVOLVED! case 1: blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.BOTTOM); break; case 2: blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.BOTTOM); break; case 3: blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.BOTTOM); break; case 4: blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.BOTTOM); break; case 5: blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.TOP); break; case 6: blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.TOP); break; case 7: blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.TOP); break; case 8: blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.TOP); break; case 9: blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.TOP); break; default: blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM); break; } } else { //If the block is a BlockColoreDoubleSlab switch (meta) { case 0: blockState = blockState.withProperty(SHADE, EnumShade.NORMAL); break; case 1: blockState = blockState.withProperty(SHADE, EnumShade.LIGHT); break; case 2: blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER); break; case 3: blockState = blockState.withProperty(SHADE, EnumShade.DARK); break; case 4: blockState = blockState.withProperty(SHADE, EnumShade.DARKER); break; default: blockState = blockState.withProperty(SHADE, EnumShade.NORMAL); break; } } return blockState; } //Converts metadata into an IBlockState. @Override public int getMetaFromState(IBlockState state) { EnumShade shade = (EnumShade) state.getValue(SHADE); if (!this.isDouble()) { EnumBlockHalf half = (EnumBlockHalf) state.getValue(HALF); //0-4 are bottom slabs, and 5-9 are the top slabs, so if the HALF property = top, //then 5 is added to the ID integer assigned to the SHADE property. This is done //to match up with how I've assigned the 9 different metadata values. (I hope //this comment made sense so I don't come back later trying to find out why I did //this and get disappointed with my former self's explanatory skills...) if (half == EnumBlockHalf.TOP) { return shade.getID() + 5; } } return shade.getID(); } //This insures that the meta block drops an item-block with the correct metadata when mined. This is //somewhat trickier than with a regular block since you don't want to drop a "top" or "bottom" half slab. //You only want to drop... well, just a slab! (Or more technically, a default, or bottom, half slab. //Of course, if you're breaking a double-slab, it shouldn't drop a block with the HALF property at all. @Override public int damageDropped(IBlockState state) { if (!this.isDouble()) { //Using my neat math tricks in conjuction with how I've set up the 9 metadata values so that //0-4 are bottom slabs and 5-9 are top slabs. if (getMetaFromState(state) > 5) { //If the block is a top slab, then drop a bottom slab. return getMetaFromState(state) - 5; } } //If the block is a bottom slab or double slab, then drop a block with a metadata between 0-4. //The value of the SHADE property is assigned to the same 5 integers for both bottom half slabs //and double slabs, so this works. Hooray for clever metadata-blockstate-math-stuff! return getMetaFromState(state); } //Used to get the last part of the unlocalized name for the item-block. //The structure of the unlocalized name is: tile.blockname.specialname.name @Override public String getSpecialName(ItemStack stack) { switch (stack.getItemDamage()) { case 0: return "normal"; case 1: return "light"; case 2: return "lighter"; case 3: return "dark"; case 4: return "darker"; default: return "normal"; } } @Override public final String getUnlocalizedName(final int metadata) { return this.getUnlocalizedName(); } //This ensures that the pick-block button (normally middle-click) will give //an item-block with the correct metadata. @Override public ItemStack getPickBlock(MovingObjectPosition target, World world, BlockPos pos) { return new ItemStack(Item.getItemFromBlock(this), 1, this.getMetaFromState(world.getBlockState(pos))); } //WIP BEYOND THIS POINT } BlockColoreSlabHalf: package com.supergeniuszeb.colore.common.blocks; import net.minecraft.block.properties.IProperty; import net.minecraft.item.ItemStack; public class BlockColoreSlabHalf extends BlockColoreSlab { public BlockColoreSlabHalf(String unlocalizedName) { super(unlocalizedName); } @Override public boolean isDouble() { return false; } } BlockColoreSlabDouble: package com.supergeniuszeb.colore.common.blocks; public class BlockColoreSlabDouble extends BlockColoreSlab { public BlockColoreSlabDouble(String unlocalizedName) { super(unlocalizedName); } @Override public boolean isDouble() { return true; } } ItemBlockColoreSlab: package com.supergeniuszeb.colore.common.blocks; import java.util.ArrayList; import java.util.List; import com.supergeniuszeb.colore.common.registry.BlockRegistry; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemSlab; import net.minecraft.item.ItemStack; /* * Wrapper class to make sure that GameRegistry.registerBlock() calls the right constructor. */ public class ItemBlockColoreSlab extends ItemSlab { public ItemBlockColoreSlab(final Block block, final BlockColoreSlabHalf slab, final BlockColoreSlabDouble doubleSlab, final Boolean stacked) { super(block, slab, doubleSlab); this.setHasSubtypes(true); this.getSubBlocks(slabList, this, 5); } public int getMetadata(int damage) { return damage; } @Override public String getUnlocalizedName(ItemStack stack) { return super.getUnlocalizedName(stack) + "." + ((IMetaBlockName)this.block).getSpecialName(stack); } public static List slabList = new ArrayList<Item>(5) {}; //This will add all the different metadata variations of the slabs //as "ItemStack"s to the slabList list. Used when adding metadata //blocks to the creative tabs. public void getSubBlocks(List slabList, Item item, int range) { for (int i = 0; i < range; ++i) { slabList.add(new ItemStack(item, 1, i)); } } } (I've commented out the other slabs, since all I really need is to get the red slab working, and then I can just do copying-and-pasting for all the others.) BlockRegistry (used to register instances of blocks): package com.supergeniuszeb.colore.common.registry; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.common.blocks.BlockColore; import com.supergeniuszeb.colore.common.blocks.BlockColoreOre; import com.supergeniuszeb.colore.common.blocks.BlockColoreSlab; import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabDouble; import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabHalf; import com.supergeniuszeb.colore.common.blocks.ItemBlockColore; import com.supergeniuszeb.colore.common.blocks.ItemBlockColoreSlab; public class BlockRegistry { //regular blocks public static BlockColore block_of_red; public static BlockColore block_of_reddish_orange; public static BlockColore block_of_orange; public static BlockColore block_of_orangish_yellow; public static BlockColore block_of_yellow; public static BlockColore block_of_yellowish_green; public static BlockColore block_of_green; public static BlockColore block_of_cyan; public static BlockColore block_of_blue; public static BlockColore block_of_indigo; public static BlockColore block_of_purple; public static BlockColore block_of_magenta; public static BlockColore block_of_brown; public static BlockColore block_of_grayscale; //half slabs public static BlockColoreSlab slab_of_red = new BlockColoreSlabHalf("slab_of_red"); /* public static BlockColoreSlabHalf slab_of_reddish_orange; public static BlockColoreSlabHalf slab_of_orange; public static BlockColoreSlabHalf slab_of_orangish_yellow; public static BlockColoreSlabHalf slab_of_yellow; public static BlockColoreSlabHalf slab_of_yellowish_green; public static BlockColoreSlabHalf slab_of_green; public static BlockColoreSlabHalf slab_of_cyan; public static BlockColoreSlabHalf slab_of_blue; public static BlockColoreSlabHalf slab_of_indigo; public static BlockColoreSlabHalf slab_of_purple; public static BlockColoreSlabHalf slab_of_magenta; public static BlockColoreSlabHalf slab_of_brown; public static BlockColoreSlabHalf slab_of_grayscale; */ //double slabs public static BlockColoreSlab slab_of_red_double = new BlockColoreSlabDouble("slab_of_red_double"); /*public static BlockColoreSlabDouble slab_of_reddish_orange_double; public static BlockColoreSlabDouble slab_of_orange_double; public static BlockColoreSlabDouble slab_of_orangish_yellow_double; public static BlockColoreSlabDouble slab_of_yellow_double; public static BlockColoreSlabDouble slab_of_yellowish_green_double; public static BlockColoreSlabDouble slab_of_green_double; public static BlockColoreSlabDouble slab_of_cyan_double; public static BlockColoreSlabDouble slab_of_blue_double; public static BlockColoreSlabDouble slab_of_indigo_double; public static BlockColoreSlabDouble slab_of_purple_double; public static BlockColoreSlabDouble slab_of_magenta_double; public static BlockColoreSlabDouble slab_of_brown_double; public static BlockColoreSlabDouble slab_of_grayscale_double;*/ //ore blocks public static BlockColoreOre essence_ore; public static void registerBlocks() { //regular blocks GameRegistry.registerBlock(block_of_red = new BlockColore("block_of_red"), ItemBlockColore.class, "block_of_red"); GameRegistry.registerBlock(block_of_reddish_orange = new BlockColore("block_of_reddish_orange"), ItemBlockColore.class, "block_of_reddish_orange"); GameRegistry.registerBlock(block_of_orange = new BlockColore("block_of_orange"), ItemBlockColore.class, "block_of_orange"); GameRegistry.registerBlock(block_of_orangish_yellow = new BlockColore("block_of_orangish_yellow"), ItemBlockColore.class, "block_of_orangish_yellow"); GameRegistry.registerBlock(block_of_yellow = new BlockColore("block_of_yellow"), ItemBlockColore.class, "block_of_yellow"); GameRegistry.registerBlock(block_of_yellowish_green = new BlockColore("block_of_yellowish_green"), ItemBlockColore.class, "block_of_yellowish_green"); GameRegistry.registerBlock(block_of_green = new BlockColore("block_of_green"), ItemBlockColore.class, "block_of_green"); GameRegistry.registerBlock(block_of_cyan = new BlockColore("block_of_cyan"), ItemBlockColore.class, "block_of_cyan"); GameRegistry.registerBlock(block_of_blue = new BlockColore("block_of_blue"), ItemBlockColore.class, "block_of_blue"); GameRegistry.registerBlock(block_of_indigo = new BlockColore("block_of_indigo"), ItemBlockColore.class, "block_of_indigo"); GameRegistry.registerBlock(block_of_purple = new BlockColore("block_of_purple"), ItemBlockColore.class, "block_of_purple"); GameRegistry.registerBlock(block_of_magenta = new BlockColore("block_of_magenta"), ItemBlockColore.class, "block_of_magenta"); GameRegistry.registerBlock(block_of_brown = new BlockColore("block_of_brown"), ItemBlockColore.class, "block_of_brown"); GameRegistry.registerBlock(block_of_grayscale = new BlockColore("block_of_grayscale"), ItemBlockColore.class, "block_of_grayscale"); //half slabs GameRegistry.registerBlock(slab_of_red, ItemBlockColoreSlab.class, "slab_of_red", slab_of_red, slab_of_red_double, false); /*GameRegistry.registerBlock(slab_of_reddish_orange = new BlockColoreSlabHalf("slab_of_reddish_orange"), ItemBlockColoreSlab.class, "slab_of_reddish_orange"); GameRegistry.registerBlock(slab_of_orange = new BlockColoreSlabHalf("slab_of_orange"), ItemBlockColoreSlab.class, "slab_of_orange"); GameRegistry.registerBlock(slab_of_orangish_yellow = new BlockColoreSlabHalf("slab_of_orangish_yellow"), ItemBlockColoreSlab.class, "slab_of_orangish_yellow"); GameRegistry.registerBlock(slab_of_yellow = new BlockColoreSlabHalf("slab_of_yellow"), ItemBlockColoreSlab.class, "slab_of_yellow"); GameRegistry.registerBlock(slab_of_yellowish_green = new BlockColoreSlabHalf("slab_of_yellowish_green"), ItemBlockColoreSlab.class, "slab_of_yellowish_green"); GameRegistry.registerBlock(slab_of_green = new BlockColoreSlabHalf("slab_of_green"), ItemBlockColoreSlab.class, "slab_of_green"); GameRegistry.registerBlock(slab_of_cyan = new BlockColoreSlabHalf("slab_of_cyan"), ItemBlockColoreSlab.class, "slab_of_cyan"); GameRegistry.registerBlock(slab_of_blue = new BlockColoreSlabHalf("slab_of_blue"), ItemBlockColoreSlab.class, "slab_of_blue"); GameRegistry.registerBlock(slab_of_indigo = new BlockColoreSlabHalf("slab_of_indigo"), ItemBlockColoreSlab.class, "slab_of_indigo"); GameRegistry.registerBlock(slab_of_purple = new BlockColoreSlabHalf("slab_of_purple"), ItemBlockColoreSlab.class, "slab_of_purple"); GameRegistry.registerBlock(slab_of_magenta = new BlockColoreSlabHalf("slab_of_magenta"), ItemBlockColoreSlab.class, "slab_of_magenta"); GameRegistry.registerBlock(slab_of_brown = new BlockColoreSlabHalf("slab_of_brown"), ItemBlockColoreSlab.class, "slab_of_brown"); GameRegistry.registerBlock(slab_of_grayscale = new BlockColoreSlabHalf("slab_of_grayscale"), ItemBlockColoreSlab.class, "slab_of_grayscale"); */ //double slabs GameRegistry.registerBlock(slab_of_red_double, ItemBlockColoreSlab.class, "slab_of_red_double", slab_of_red, slab_of_red_double, true); /*GameRegistry.registerBlock(slab_of_reddish_orange_double = new BlockColoreSlabDouble("slab_of_reddish_orange_double"), ItemBlockColoreSlab.class, "slab_of_reddish_orange_double"); GameRegistry.registerBlock(slab_of_orange_double = new BlockColoreSlabDouble("slab_of_orange_double"), ItemBlockColoreSlab.class, "slab_of_orange_double"); GameRegistry.registerBlock(slab_of_orangish_yellow_double = new BlockColoreSlabDouble("slab_of_orangish_yellow_double"), ItemBlockColoreSlab.class, "slab_of_orangish_yellow_double"); GameRegistry.registerBlock(slab_of_yellow_double = new BlockColoreSlabDouble("slab_of_yellow_double"), ItemBlockColoreSlab.class, "slab_of_yellow_double"); GameRegistry.registerBlock(slab_of_yellowish_green_double = new BlockColoreSlabDouble("slab_of_yellowish_green_double"), ItemBlockColoreSlab.class, "slab_of_yellowish_green_double"); GameRegistry.registerBlock(slab_of_green_double = new BlockColoreSlabDouble("slab_of_green_double"), ItemBlockColoreSlab.class, "slab_of_green_double"); GameRegistry.registerBlock(slab_of_cyan_double = new BlockColoreSlabDouble("slab_of_cyan_double"), ItemBlockColoreSlab.class, "slab_of_cyan_double"); GameRegistry.registerBlock(slab_of_blue_double = new BlockColoreSlabDouble("slab_of_blue_double"), ItemBlockColoreSlab.class, "slab_of_blue_double"); GameRegistry.registerBlock(slab_of_indigo_double = new BlockColoreSlabDouble("slab_of_indigo_double"), ItemBlockColoreSlab.class, "slab_of_indigo_double"); GameRegistry.registerBlock(slab_of_purple_double = new BlockColoreSlabDouble("slab_of_purple_double"), ItemBlockColoreSlab.class, "slab_of_purple_double"); GameRegistry.registerBlock(slab_of_magenta_double = new BlockColoreSlabDouble("slab_of_magenta_double"), ItemBlockColoreSlab.class, "slab_of_magenta_double"); GameRegistry.registerBlock(slab_of_brown_double = new BlockColoreSlabDouble("slab_of_brown_double"), ItemBlockColoreSlab.class, "slab_of_brown_double"); GameRegistry.registerBlock(slab_of_grayscale_double = new BlockColoreSlabDouble("slab_of_grayscale_double"), ItemBlockColoreSlab.class, "slab_of_grayscale_double"); */ GameRegistry.registerBlock(essence_ore = new BlockColoreOre("essence_ore"), ItemBlockColore.class, "essence_ore"); } } BlockRenderRegistry (used to register block models and item-block models... I am aware I haven't registered the slab models or anything yet, but nothing in this class affects the functionality of the blocks, so I'm not going to add anything here until the slabs work as intended and all that's left is the rendering side of things.): package com.supergeniuszeb.colore.client.render; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import com.supergeniuszeb.colore.Reference; import com.supergeniuszeb.colore.common.registry.BlockRegistry; import com.supergeniuszeb.colore.utility.ModUtilities; //All this handles are the item-block models, not the actual block models, which are //defined in the .json files. public class BlockRenderRegistry { //This method is called by the registerRenders method every time it adds an item-block model. public static void registerRender(Block block) { Item item = Item.getItemFromBlock(block); Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory")); } //This method is called by the init method every time it adds a meta item-block model. public static void registerRender(Block block, int meta, String fileName) { Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), meta, new ModelResourceLocation(Reference.MOD_ID + ":" + fileName, "inventory")); } public static void preInit() { for (String shade : ModUtilities.shadeList) { ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_red), new ResourceLocation(Reference.MOD_ID, "block_of_red_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_reddish_orange), new ResourceLocation(Reference.MOD_ID, "block_of_reddish_orange_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_orange), new ResourceLocation(Reference.MOD_ID, "block_of_orange_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_orangish_yellow), new ResourceLocation(Reference.MOD_ID, "block_of_orangish_yellow_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_yellow), new ResourceLocation(Reference.MOD_ID, "block_of_yellow_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_yellowish_green), new ResourceLocation(Reference.MOD_ID, "block_of_yellowish_green_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_green), new ResourceLocation(Reference.MOD_ID, "block_of_green_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_cyan), new ResourceLocation(Reference.MOD_ID, "block_of_cyan_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_blue), new ResourceLocation(Reference.MOD_ID, "block_of_blue_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_indigo), new ResourceLocation(Reference.MOD_ID, "block_of_indigo_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_purple), new ResourceLocation(Reference.MOD_ID, "block_of_purple_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_magenta), new ResourceLocation(Reference.MOD_ID, "block_of_magenta_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_brown), new ResourceLocation(Reference.MOD_ID, "block_of_brown_" + shade)); ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_grayscale), new ResourceLocation(Reference.MOD_ID, "block_of_grayscale_" + shade)); } for (String color : ModUtilities.baseColorList) { ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.essence_ore), new ResourceLocation(Reference.MOD_ID, "essence_ore_" + color)); } } public static void init() { int i = 0; for (String shade : ModUtilities.shadeList) { registerRender(BlockRegistry.block_of_red, i, "block_of_red_" + shade); registerRender(BlockRegistry.block_of_reddish_orange, i, "block_of_reddish_orange_" + shade); registerRender(BlockRegistry.block_of_orange, i, "block_of_orange_" + shade); registerRender(BlockRegistry.block_of_orangish_yellow, i, "block_of_orangish_yellow_" + shade); registerRender(BlockRegistry.block_of_yellow, i, "block_of_yellow_" + shade); registerRender(BlockRegistry.block_of_yellowish_green, i, "block_of_yellowish_green_" + shade); registerRender(BlockRegistry.block_of_green, i, "block_of_green_" + shade); registerRender(BlockRegistry.block_of_cyan, i, "block_of_cyan_" + shade); registerRender(BlockRegistry.block_of_blue, i, "block_of_blue_" + shade); registerRender(BlockRegistry.block_of_indigo, i, "block_of_indigo_" + shade); registerRender(BlockRegistry.block_of_purple, i, "block_of_purple_" + shade); registerRender(BlockRegistry.block_of_magenta, i, "block_of_magenta_" + shade); registerRender(BlockRegistry.block_of_brown, i, "block_of_brown_" + shade); registerRender(BlockRegistry.block_of_grayscale, i, "block_of_grayscale_" + shade); i++; } i = 0; for (String color : ModUtilities.baseColorList) { registerRender(BlockRegistry.essence_ore, i, "essence_ore_" + color); i++; } } } I hope you all can help me find what silly mistakes I've made, as well as help me understand all of this better. My head is spinning in squares right now...
  11. Mod website and download: http://supergeniuszeb.com/project/colore/ Release trailer: 1.2: The Super Update Release Trailer: The mod has now been updated to 1.10! It took exactly zero effort because literally nothing needed to be changed other than the version number! Enjoy! Pictures Noticing a lack of color in your Minecraft world? Well this mod has plenty of it! The Colore Mod adds new ores to your world, containing the essence of color itself! After mining and refining the essence, you can craft blocks, tools, and armor! You can also combine essences to create up to 70 different colors! This mod is great for pixel-artists, builders, and for anyone looking to add some color to their Minecraft world! And even more is planned to be added in future updates, so the possibilities will only grow! This is my first-ever Minecraft mod, and I enjoyed coding it… and I hope you enjoy using it as well! Planned additions: Fluids Transparent tools & armor Bows Shields If you want to put this mod in a public modpack, please contact me first, and make sure to give me credit in the modpack's description and provide a link to this website. Comments & feedback are welcome! Thanks for checking out my mod!
  12. Thanks for the tips and suggestions, everyone! It turned out that for my particular problems, wiping my class files clean and starting fresh helped me to figure out how to get several things working and how certain things are supposed to work, and I've restructured my mod to be more modular, consistent, organized, and compatible with the pre-init/init/post-init structure. I'll keep in mind what you all have said, and hopefully my mod's development should go smoothly now. (And when I'm finished I'll make sure to post a topic here showing you the completed mod!) Again, thanks for the help.
  13. So in trying to mod for the first time I'm finding out just how difficult it can be when you follow one set of tutorials and then jump to another one because the first one never told ou how to implement metadata blocks, but then the 2nd one is setting up the classes and functions in different files with different class/function names and then this 3rd tutorial you go to has more information you need but apparently the way you're setting up your code won't allow you to implement the solution because you're using a different structure and other crazy confusing stuff. Basically, I don't know how to set up my mod's code. I understand most of the basic concepts of registering blocks/items into the game, as well as their models, but trying to follow a tutorial is difficult when you've never modded before and the classes, files, and methods of getting things done don't work with the way you've already set up your code. So what do you think is the best structure for a 1.8 mod? Should an item's model be registered in the same class file as the item itself? What exactly is supposed to be done during pre-init, init, and post-init? Right now I feel my code is full of patchwork methods of doing things, and some things work but are accomplished inconsistently from other things since I've followed so many different tutorials. I'm sure this probably sounds like a vague question, but I feel like I need to do a rewrite from the ground up... except that I don't want to use a structure of doing things that is inconsistent or inefficient or won't work with certain things like metadata blocks with textures based on metadata. So how should I set up the packages, and what is the best way to register items and blocks (especially for a mod that happens to be about monochrome colored blocks/items in 14 colors and 5 shades, making nearly every block/item identical, aside from some additional special blocks/items), as well as their models/textures? I've seen several tutorials, and they all seem to put various methods/classes/variables/etc. in different places (and to make it even more confusing, they give them different names as well), and right now I'm confused as to which path to follow.
  14. EDIT: After rewriting a lot of my code, restructuring the classes and packages, and reading deeper into tutorials, I eventually figured out how to get it done. I wound up using just a single "BlockColore" class with 5 metadata states for the 5 different shades. I considered making the 14 colors be the metadata instead, but I decided against it, as I didn't want to limit myself to 16 base colors, although I don't currently plan on having more than my current 14. Actually, now that I think about it, I probably should've made the colors be the metadata. But I've finished coding it all and getting it working, so I'm not going to bother changing it unless I need to. (As in I have to rewrite my mod from ground up because of a huge Minecraft/Forge change or the official Mod API finally gets released.) I gave up on trying to color the blocks/items using a color-map or something... maybe I'll try that again in the future. Thanks to everyone who responded and helped me on this question. I'm currently working on my first-ever Minecraft mod, which will add mono-colored blocks (and "essences of color" items used to craft them) that come in 14 base colors. My plan is to set it up so that I use metadata to define whether an essence item/color block is a "lighter", "light", "normal", "dark", or "darker" variant to make a total of 70 different blocks and 70 different colors. For example, there would be a "block_of_red" block which would use metadata to determine whether it is a "Block of Red", "Block of Light Red", "Block of Lighter Red", "Block of Dark Red", or "Block of Darker Red". (And yes, I am aware I could just call it "Red Block", but "Block of Red" sounds cooler.) My problem is that I'm having trouble trying to figure out how to implement the metadata. (And I REALLY don't want to just take the lazy/boring route and make 70 separate blocks.) How some of my classes are currently set up: I have an "init" package which contains classes used for registering all the individual items/blocks, an "items" package containing the base classes for different item types ("essences", swords, pickaxes, etc.), and a "blocks" package containing the base classes for different block types (regular blocks and ore blocks). blocks package - BlockColore.java (base basic block class - as you can see I've commented out the code I'm working on for the metadata) package com.supergeniuszeb.colore.blocks; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockState; import net.minecraft.util.IStringSerializable; import com.supergeniuszeb.colore.ModCreativeTabs; public class BlockColore extends Block { public BlockColore(String unlocalizedName) { super(Material.rock); this.setHardness(1.5f); this.setHarvestLevel("pickaxe", 0); this.setResistance(10.0f); this.setUnlocalizedName(unlocalizedName); this.setCreativeTab(ModCreativeTabs.blockTab); } /** public static final PropertyEnum SHADE = PropertyEnum.create("shade", BlockColore.EnumType.class); public enum EnumType implements IStringSerializable { DARKER(0, "darker"), DARK(1, "dark"), NORMAL(2, "normal"), LIGHT(3, "light"), LIGHTER(4, "lighter"); private int ID; private String name; private EnumType(int ID, String name) { this.ID = ID; this.name = name; } @Override public String getName() { return null; } @Override public String toString() { return getName(); } }**/ /** @Override protected BlockState createBlockState() { return new BlockState(this, new IProperty[] {SHADE}); }**/ /** @Override public IBlockState getStateFromMeta(int meta) { return getDefaultState().withProperty(SHADE, value) }**/ } items package - ItemEssence.java (base "essence" item class) package com.supergeniuszeb.colore.items; import java.util.List; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import com.supergeniuszeb.colore.ModCreativeTabs; //Special thanks to coolAlias and EverythingGames, users from the Forge forums, for helping //me with figuring out how to optimize my item-and-block-registering code. public class ItemEssence extends Item { public ItemEssence(String unlocalizedName) { super(); this.setHasSubtypes(true); this.setUnlocalizedName(unlocalizedName); this.setMaxStackSize(64); this.setCreativeTab(ModCreativeTabs.itemTab); } public String essenceShade = new String(); public String getUnlocalizedName(ItemStack stack) { if (stack.getItemDamage() == -2) { essenceShade = "darker"; } else if (stack.getItemDamage() == -1) { essenceShade = "dark"; } else if (stack.getItemDamage() == 0) { essenceShade = "normal"; } else if (stack.getItemDamage() == 1) { essenceShade = "light"; } else if (stack.getItemDamage() == 2) { essenceShade = "lighter"; } return super.getUnlocalizedName() + "." + (essenceShade); } public void getSubItems(Item itemIn, ModCreativeTabs tab, List subItems) { subItems.add(new ItemStack(itemIn, 1, -2)); subItems.add(new ItemStack(itemIn, 1, -1)); subItems.add(new ItemStack(itemIn, 1, 0)); subItems.add(new ItemStack(itemIn, 1, 1)); subItems.add(new ItemStack(itemIn, 1, 2)); } } init package - BlockRegistry.java (class containing code for registering the individual blocks) package com.supergeniuszeb.colore.init; import java.lang.reflect.Field; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.Reference; import com.supergeniuszeb.colore.blocks.BlockColore; import com.supergeniuszeb.colore.blocks.BlockColoreOre; //Special thanks to coolAlias and EverythingGames, users from the Forge forums, for helping //me with figuring out how to optimize my item-and-block-registering code. public class BlockRegistry { //pure blocks public static BlockColore block_of_red = new BlockColore("block_of_red"); public static BlockColore block_of_reddish_orange = new BlockColore("block_of_reddish_orange"); public static BlockColore block_of_orange = new BlockColore("block_of_orange"); public static BlockColore block_of_orangish_yellow = new BlockColore("block_of_orangish_yellow"); public static BlockColore block_of_yellow = new BlockColore("block_of_yellow"); public static BlockColore block_of_yellowish_green = new BlockColore("block_of_yellowish_green"); public static BlockColore block_of_green = new BlockColore("block_of_green"); public static BlockColore block_of_cyan = new BlockColore("block_of_cyan"); public static BlockColore block_of_blue = new BlockColore("block_of_blue"); public static BlockColore block_of_indigo = new BlockColore("block_of_indigo"); public static BlockColore block_of_purple = new BlockColore("block_of_purple"); public static BlockColore block_of_magenta = new BlockColore("block_of_magenta"); public static BlockColore block_of_brown = new BlockColore("block_of_brown"); public static BlockColore block_of_grayscale = new BlockColore("block_of_grayscale"); public static BlockColore rainbow_block = new BlockColore("rainbow_block"); //ore blocks public static BlockColoreOre red_ore = new BlockColoreOre("red_ore"); public static BlockColoreOre orange_ore = new BlockColoreOre("orange_ore"); public static BlockColoreOre yellow_ore = new BlockColoreOre("yellow_ore"); public static BlockColoreOre green_ore = new BlockColoreOre("green_ore"); public static BlockColoreOre blue_ore = new BlockColoreOre("blue_ore"); public static BlockColoreOre purple_ore = new BlockColoreOre("purple_ore"); public static BlockColoreOre brown_ore = new BlockColoreOre("brown_ore"); public static BlockColoreOre white_ore = new BlockColoreOre("white_ore"); public static BlockColoreOre black_ore = new BlockColoreOre("black_ore"); public static void registerBlocks() { try { for (Field f : BlockRegistry.class.getFields()) { // get all declared fields in the BlockRegistry class if (Block.class.isAssignableFrom(f.getType())) { // if a field is a block, fetch it and register it Block block = (Block) f.get(null); if (block != null) { String name = block.getUnlocalizedName(); GameRegistry.registerBlock(block, name.substring(name.lastIndexOf(".") + 1)); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } public static void registerRenders() { try { for (Field f : BlockRegistry.class.getFields()) { // get all declared fields in the BlockRegistry class if (Block.class.isAssignableFrom(f.getType())) { // if a field is a block, fetch it and register its renders Block block = (Block) f.get(null); if (block != null) { registerRender(block); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } //This method is called by the registerRenders method every time it adds an item. public static void registerRender(Block block) { Item item = Item.getItemFromBlock(block); Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory")); } } init package - ItemRegistry.java (code for registering "essence" items) package com.supergeniuszeb.colore.init; import java.lang.reflect.Field; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.Reference; import com.supergeniuszeb.colore.items.ItemEssence; //is static needed? public class ItemRegistry { //refined essences public static ItemEssence essence_of_red = new ItemEssence("essence_of_red"); public static ItemEssence essence_of_reddish_orange = new ItemEssence("essence_of_reddish_orange"); public static ItemEssence essence_of_orange = new ItemEssence("essence_of_orange"); public static ItemEssence essence_of_orangish_yellow = new ItemEssence("essence_of_orangish_yellow"); public static ItemEssence essence_of_yellow = new ItemEssence("essence_of_yellow"); public static ItemEssence essence_of_yellowish_green = new ItemEssence("essence_of_yellowish_green"); public static ItemEssence essence_of_green = new ItemEssence("essence_of_green"); public static ItemEssence essence_of_cyan = new ItemEssence("essence_of_cyan"); public static ItemEssence essence_of_blue = new ItemEssence("essence_of_blue"); public static ItemEssence essence_of_indigo = new ItemEssence("essence_of_indigo"); public static ItemEssence essence_of_purple = new ItemEssence("essence_of_purple"); public static ItemEssence essence_of_magenta = new ItemEssence("essence_of_magenta"); public static ItemEssence essence_of_brown = new ItemEssence("essence_of_brown"); public static ItemEssence essence_of_grayscale = new ItemEssence("essence_of_grayscale"); public static ItemEssence rainbow_essence = new ItemEssence("rainbow_essence"); //unrefined essences public static ItemEssence unrefined_red = new ItemEssence("unrefined_red"); public static ItemEssence unrefined_orange = new ItemEssence("unrefined_orange"); public static ItemEssence unrefined_yellow = new ItemEssence("unrefined_yellow"); public static ItemEssence unrefined_green = new ItemEssence("unrefined_green"); public static ItemEssence unrefined_blue = new ItemEssence("unrefined_blue"); public static ItemEssence unrefined_purple = new ItemEssence("unrefined_purple"); public static ItemEssence unrefined_brown = new ItemEssence("unrefined_brown"); public static ItemEssence unrefined_white = new ItemEssence("unrefined_white"); public static ItemEssence unrefined_black = new ItemEssence("unrefined_black"); public static void registerItems() { try { for (Field f : ItemRegistry.class.getFields()) { // get all declared fields in the ItemRegistry class if (Item.class.isAssignableFrom(f.getType())) { // if a field is an item, fetch it and register it Item item = (Item) f.get(null); if (item != null) { String name = item.getUnlocalizedName(); GameRegistry.registerItem(item, name.substring(name.lastIndexOf(".") + 1)); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } public static void registerRenders() { try { for (Field f : ItemRegistry.class.getFields()) { // get all declared fields in the ItemRegistry class if (Item.class.isAssignableFrom(f.getType())) { // if a field is an item, fetch it and register its renders Item item = (Item) f.get(null); if (item != null) { registerRender(item); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } //This method is called by the registerRenders method every time it adds an item. public static void registerRender(Item item) { Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, meta, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory")); } } I've tried reading some tutorials, but due to differences between the code in the tutorials and the way I've written my code, I've had trouble trying to implement it and it's become very confusing. Do I need to make a separate base class file for all 14 base color blocks (and likewise for the "essence items")? I would prefer not to do that, since all the "essence" items are literally identical except for their color, and likewise for the blocks. (And to be honest, if it weren't for the 4-bit limitations of metadata, I would only have one block with 70 different blockstates, and likewise for the "essence" items.) Or is that actually how it's supposed to be done? Am I taking the wrong approach? What's the best way to approach this? (without using tile-entities, since I want these to be pushable by pistons)
  15. Luckily, my whole mod is about blocks and items that are identical aside from their color. Anyway, literally right after posting my previous post I noticed something. I had set up my packages and classes like so: I realized that if I have an items package and a blocks package, then wouldn't it make more sense to put the base item/block classes in there and have the init package contain the registration classes? So I began doing some heavy refactoring and changed my code structure to this: So I've tested everything and it all works fine, aside from some missing textures which are missing because I haven't made them yet. () I've basically separated the base item/block classes from the initialization/registration of the items/blocks that use them, which I think helps with making my code more modular and organized. What do you think? For reference, here are the new classes:
  16. @coolAlias and EverythingGames: Thanks! I tried your suggestions and they worked? I've created a new class/.java file for my items called ItemEssence and pretty much deprecated the older ModItems.java file (in other words I've commented out most of the references to it in the mian code and in the proxies so it isn't in use but can still be accessed for the time being in case I need to borrow any code from it or something.) I tried starting up the test client and it works! Here's what is in the new ItemEssence.java file: package com.supergeniuszeb.colore.init; import java.lang.reflect.Field; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.ModCreativeTabs; import com.supergeniuszeb.colore.Reference; //Special thanks to coolAlias and EverythingGames, users from the Forge forums, for helping //me with figuring out how to optimize my item-and-block-registering code. public class ItemEssence extends Item { public ItemEssence(String unlocalizedName) { this.setUnlocalizedName(unlocalizedName); this.setMaxStackSize(64); this.setCreativeTab(ModCreativeTabs.itemTab); } public static class ItemRegistry { //refined essences public static ItemEssence essence_of_red = new ItemEssence("essence_of_red"); public static ItemEssence essence_of_reddish_orange = new ItemEssence("essence_of_reddish_orange"); public static ItemEssence essence_of_orange = new ItemEssence("essence_of_orange"); public static ItemEssence essence_of_orangish_yellow = new ItemEssence("essence_of_orangish_yellow"); public static ItemEssence essence_of_yellow = new ItemEssence("essence_of_yellow"); public static ItemEssence essence_of_yellowish_green = new ItemEssence("essence_of_yellowish_green"); public static ItemEssence essence_of_green = new ItemEssence("essence_of_green"); public static ItemEssence essence_of_cyan = new ItemEssence("essence_of_cyan"); public static ItemEssence essence_of_blue = new ItemEssence("essence_of_blue"); public static ItemEssence essence_of_indigo = new ItemEssence("essence_of_indigo"); public static ItemEssence essence_of_purple = new ItemEssence("essence_of_purple"); public static ItemEssence essence_of_magenta = new ItemEssence("essence_of_magenta"); public static ItemEssence essence_of_brown = new ItemEssence("essence_of_brown"); public static ItemEssence essence_of_grayscale = new ItemEssence("essence_of_grayscale"); public static ItemEssence rainbow_essence = new ItemEssence("rainbow_essence"); //unrefined essences public static ItemEssence unrefined_red = new ItemEssence("unrefined_red"); public static ItemEssence unrefined_orange = new ItemEssence("unrefined_orange"); public static ItemEssence unrefined_yellow = new ItemEssence("unrefined_yellow"); public static ItemEssence unrefined_green = new ItemEssence("unrefined_green"); public static ItemEssence unrefined_blue = new ItemEssence("unrefined_blue"); public static ItemEssence unrefined_purple = new ItemEssence("unrefined_purple"); public static ItemEssence unrefined_brown = new ItemEssence("unrefined_brown"); public static ItemEssence unrefined_white = new ItemEssence("unrefined_white"); public static ItemEssence unrefined_black = new ItemEssence("unrefined_black"); public static void registerItems() { try { for (Field f : ItemRegistry.class.getFields()) { // get all declared fields in the ItemRegistry class if (Item.class.isAssignableFrom(f.getType())) { // if a field is an item, fetch it and register it Item item = (Item) f.get(null); if (item != null) { String name = item.getUnlocalizedName(); GameRegistry.registerItem(item, name.substring(name.lastIndexOf(".") + 1)); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } public static void registerRenders() { try { for (Field f : ItemRegistry.class.getFields()) { // get all declared fields in the ItemRegistry class if (Item.class.isAssignableFrom(f.getType())) { // if a field is an item, fetch it and register its renders Item item = (Item) f.get(null); if (item != null) { registerRender(item); } } } } catch(Exception e) { // catch so game won't crash, but log so issue can still be found and fixed e.printStackTrace(); } } //This method is called by the registerRenders method every time it adds an item. public static void registerRender(Item item) { Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory")); } } } What do you think? Any other improvements I could make? Now that I have the item code working it should be fairly easy for me to duplicate this for the blocks and other things I'm adding in my mod.
  17. So I'm pretty new to modding, and I'm working on my first mod, which will add 70 monocolored blocks to the game. (14 colors with 5 shades stored in metadata and blockstates.) The blocks are made out items called "color essences" and you'll be able to craft combinations of essences to get the different colors and shades. I'm trying to shorten the code for all the registering and adding in of items, and I've run into a problem. I can't figure out how to do it. I've been trying to use arrays and maps and sets and all sorts of things to prevent from having to call the same method 14 times. Here are some of my classes: (main class) Colore.java package com.supergeniuszeb.colore; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.init.ModBlocks; import com.supergeniuszeb.colore.init.ModItems; import com.supergeniuszeb.colore.init.ModRecipes; import com.supergeniuszeb.colore.init.ModTools; import com.supergeniuszeb.colore.proxy.CommonProxy; @Mod(modid = Reference.MOD_ID, name = Reference.MOD_NAME, version = Reference.VERSION) public class Colore { @SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS) public static CommonProxy proxy; public static final ModCreativeTabs tab1 = new ModCreativeTabs("tab1"); @EventHandler public void preInit(FMLPreInitializationEvent event) { //Initializes and registers blocks & items. ModBlocks.init(); ModBlocks.register(); ModItems.init(); ModItems.register(); ModTools.init(); ModTools.register(); //Runs the ore generation code. See ModGeneration.java. GameRegistry.registerWorldGenerator(new ModGeneration(), 0); } @EventHandler public void init(FMLInitializationEvent event) { proxy.registerRenders(); //Adds all crafting & smelting recipes. ModRecipes.addRecipes(); } @EventHandler public void postInit(FMLPostInitializationEvent event) { } } (in package "proxy") ClientProxy.java package com.supergeniuszeb.colore.proxy; import com.supergeniuszeb.colore.init.ModBlocks; import com.supergeniuszeb.colore.init.ModItems; import com.supergeniuszeb.colore.init.ModTools; //Everything in here is done client-side. //This class and CommonProxy.java are used to keep server-side and client-side stuff separate. public class ClientProxy extends CommonProxy { @Override public void registerRenders() { ModBlocks.registerRenders(); ModItems.registerRenders(); ModTools.registerRenders(); } } (in package "proxy") CommonProxy.java package com.supergeniuszeb.colore.proxy; //Everything in here is done server-side. //This class and ClientProxy.java are used to keep server-side and client-side stuff separate. public class CommonProxy { public void registerRenders() { } } (in package "init") ModItems.java package com.supergeniuszeb.colore.init; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraftforge.fml.common.registry.GameRegistry; import com.supergeniuszeb.colore.Colore; import com.supergeniuszeb.colore.Reference; public class ModItems extends Item { public static Item essence_of_red; public static Item essence_of_reddish_orange; public static Item essence_of_orange; public static Item essence_of_orangish_yellow; public static Item essence_of_yellow; public static Item essence_of_yellowish_green; public static Set<Item> colorSet = new LinkedHashSet<>(); //The empty "<>" will only work in Java 7+ { //IMPORTANT! Methods MUST be called within this main class' methods or in curly braces. colorSet.add(essence_of_red); colorSet.add(essence_of_orange); } public static String[] essenceList = { "essence_of_red", "essence_of_orange" }; public static Object[] colorArray = colorSet.toArray(); //refined essences //unrefined essences public static Item unrefined_red; public static void init() { int i = 0; for (Object color : colorArray) { color = new Item().setUnlocalizedName(essenceList[i]).setCreativeTab(Colore.tab1); i++; } //refined essences //essence_of_red = new Item().setUnlocalizedName("essence_of_red").setCreativeTab(Colore.tab1); //unrefined essences unrefined_red = new Item().setUnlocalizedName("unrefined_red").setCreativeTab(Colore.tab1); } public static void register() { for (Item color : colorSet) { GameRegistry.registerItem(color, color.getUnlocalizedName().substring(5)); } //refined essences //GameRegistry.registerItem(essence_of_red, essence_of_red.getUnlocalizedName().substring(5)); //unrefined essences GameRegistry.registerItem(unrefined_red, unrefined_red.getUnlocalizedName().substring(5)); } public static void registerRenders() { for (Item color : colorSet) { registerRender(color); } //refined essences //registerRender(essence_of_red); //unrefined essences registerRender(unrefined_red); } //This method is called by the registerRenders method every time it adds an item. public static void registerRender(Item item) { Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory")); } } I've based a lot of my code on the , in case you're wondering why my code is written in this way. If you need to see any more of my classes just let me know. I've tried looking at other modding tutorials but a lot of them set up the proxies and items and stuff in a different way, and I haven't got a clue as to what the most modular, efficient, and wisest solution is. Any suggestions? I keep getting errors when it tries to register the recipes for the blocks, which I assume is due to improper Item registering. I apologize for my somewhat messy code. I've commented out a lot of things during testing and I'm trying to focus on getting just one or 2 items working so I can duplicate it for all the others, rather than have to make changes to several different variables and methods and such.
×
×
  • Create New...

Important Information

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