Jump to content

Rohzek

Forge Modder
  • Posts

    84
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Rohzek

  1. Show how you apply your creative tab to your items and how you declared more than one.

     

    Right now, I have them all declared at the top of my main class, just like in the op, which probably isn't the correct way to do it.

    public static final CustomCreativeTab CUSTOM_TAB = new CustomCreativeTab("myCustomTab", Items.APPLE);
    public static final CustomCreativeTab CUSTOM_TAB_ONE = new CustomCreativeTab("myCustomTab1", Items.STICK);
    ... etc
    

    As for how I "apply" them my items, I have the different types separated by classes (Food, ingots, tools, etc) But in each, I just call setCreativeTab in their constructors, and tell it which tab it belongs in.

    public CustomItems(String names)
    {
    setNames(names);
    setCreativeTab(Main.CUSTOM_TAB);
    }
    
    private void setNames(String name)
    {
    setUnlocalizedName(name);
    setRegistryName(name);
    }
    

    Which works for the first two tabs, but not any more, which is weird. I'm assuming either the items, or the tabs are being initialized in an order that stops one of them from seeing the other. Not sure which way.

     

    I do this, works for me.

    public static CreativeTabs buildingBlocks = new CreativeTabs("moreBuildingBlocks"){
    	@Override
    	public Item getTabIconItem(){
    		return Item.getItemFromBlock(BBBlocks.cotswoldBricks);
    	}
    };

     

    Keep in mind this is 1.10.2, in 1.11 I believe you need to return a ItemStack

     

    Yeah. This is what I have:

    public class CustomCreativeTab extends CreativeTabs
    {
    private ItemStack iconItem;
    
    private ItemSorter itemSorter = new ItemSorter();
    
    public CustomCreativeTab(String label, Item item)
    {
    	super(label);
    	iconItem = new ItemStack(item);
    }
    
    @Override
    public ItemStack getTabIconItem() 
    {
    	return iconItem;
    }
    
    @Override
    public void displayAllRelevantItems(NonNullList<ItemStack> items) 
    {
    	super.displayAllRelevantItems(items);
    
    	Collections.sort(items, itemSorter);
    }
    
    // Sorts items in alphabetical order using their display names, blocks on top
    private static class ItemSorter implements Comparator<ItemStack> 
    {
    
    	@Override
    	public int compare(ItemStack o1, ItemStack o2) 
    	{
    		Item item1 = o1.getItem();
    		Item item2 = o2.getItem();
    
    		// If item1 is a block and item2 isn't, sort item1 before item2
    		if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) 
    		{
    			return -1;
    		}
    
    		// If item2 is a block and item1 isn't, sort item1 after item2
    		if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock)))
    		{
    			return 1;
    		}
    
    		String displayName1 = o1.getDisplayName();
    		String displayName2 = o2.getDisplayName();
    
    		int result = displayName1.compareToIgnoreCase(displayName2);
    
    		return result;
    	}
    }
    }
    

  2. What is the proper way of registering Creative Tabs?

     

    Right now, I have them at the top of my main class between declaring the instance, and the preinit event just, like this:

    public static final CustomCreativeTabs SP_TAB = new CustomCreativeTabs("myTab", Items.APPLE);
    

    Which works fine if I only have one of them. For some reason, though, If I try to make more than 2, not all of my items and blocks will show up in the last one. If I make 4 or more. no items or blocks show up in the 4th+

  3. You know what? It needed to be registered on the terrain event bus, not the event bus. Now, it's working but my attempt at placing my own block in it's place crashes.

    World world = event.getWorld();
    BlockPos pos = event.getPos();
    EventType type = event.getType();
    
    if(type == EventType.PUMPKIN)
    {
    event.setResult(Result.DENY);
    if(!world.isRemote)
    {
    	LogHelper.debug("I blocked a pumpkin spawn");
    	world.setBlockState(pos, SPBlocks.PUMPKIN_SP.getDefaultState());
    }
    }
    

     

    EDIT:

     

    Because the pos it always spits out, is at y level 0. I'm quite confused here.

  4. setCustomName is a method in TileEntityChest specifically. And it exist is 1.11

     

    Ah. That explains then. I wasn't thinking, and only looked in TileEntity.

     

    Thanks for your reply. I will now have to learn about NBT. I thought making the chests my mod spawns in unbreakable would be easy but i've had to learn a ton to get this close. Figuring out NBT should be fun. Any good guides you're familiar with?

     

    The NBT is pretty simple, for both items and tile entities.

     

    You would do something like:

     

    NBTTagCompound myCompound = tileEntity.getTileData();
    
    myCompound.setString("keyToSave", "valueToSave");
    

     

    Keep in mind TileEntity#getTileData (in 1.11 anyway) specifically checks to see if the NBTTagCompound is null, and if it is, sets it to a new one. You should probably check to make sure it's not null before reading it or writing to it, anyway though.

     

    and to retrieve it later, you would do this:

     

    String myName = myCompound.getString("keyToSave");
    

  5. I don't know much in the way of what's wrong with your current issue, but as an alternative you could try saving and loading the String you want in the tile entity's NBT, instead of using TileEntity#setCustomName, which seems to be more future proof, as I went to investigate that method, and couldn't find it in the TileEntity class for 1.11 (which is what I am currently working with).

  6. Could you show the code where you catch the event ?

    @Mod.EventBusSubscriber
    public class DecorateBiomeEventSP 
    {
    @SubscribeEvent
    public static void onDecorateBiome(DecorateBiomeEvent.Decorate event)
    {
    	World world = event.getWorld();
    	BlockPos pos = event.getPos();
    	EventType type = event.getType();
    
    	if(type == EventType.PUMPKIN)
    	{
    		event.setResult(Result.DENY);
    		world.setBlockState(pos, SPBlocks.PUMPKIN_SP.getDefaultState());
    	}
    }
    }
    

    Mind that will only work for things like pumpkins. If you wanted to replace--say--cobblestone in villages, you'd have a much harder time.

     

    I'm only replacing the melons and pumpkins. The melons use the same texture so I just changed the drop you get with the harvest drops event to my custom one, but my custom pumpkin removes the face (and will make you carve one on, to get the vanilla pumpkin... unless I can make a custom block work to spawn the snow golem) so I'm trying to replace them.

  7. When are you calling this?

     

    I was calling it during the preinit of my main class

    public static void PreInit(FMLPreInitializationEvent PreEvent)
    {
         MinecraftForge.EVENT_BUS.register(new LoadModelEvent());
    }
    

     

    I also tried (after reading through Choonster's link) making it static, and making that

     

    public static void PreInit(FMLPreInitializationEvent PreEvent)
    {
         MinecraftForge.EVENT_BUS.register(LoadModelEvent.class);
    }
    

     

    Which also didn't work. I then tried removing that, and using:

     

    @Mod.EventBusSubscriber
    public class LoadModelEvent 
    {
         ...
    }
    

     

    Which runs, and gets a nullpointerexception because the items aren't loaded yet...

    Attempting to load the items by registering them in the event too instead of normal fixes that, but then they get initialized as being from

    minecraft instead of being from my MODID

     

    Exception loading model for variant minecraft:testitemstage0#inventory for item "minecraft:testitem", normal location exception: 
    

     

    Sorry, I am 100% thoroughly lost and confused.

  8. I seem to be failing to properly register my ModelRegistryEvent, as it seems it doesn't complain because that method never runs?

     

    I've tried registering it with the forge event bus in both my Main, and ClientProxy and neither works...

     

    ...This is probably all wrong?

     

    MinecraftForge.EVENT_BUS.register(new LoadModelEvent());
    

     

    LoadModelEvent:

    ...
    
    @SubscribeEvent
    public void onModelRegistry(ModelRegistryEvent event)
    {
         testItems.registerRenders();
    }
    

     

    TestItems:

    ...
    
    public static void registerRenders() 
    {
    registerRender(testItem, 0, "Stage0");
    registerRender(testItem, 1, "Stage1");
    registerRender(testItem, 2, "Stage2");
    }
    
    public static void registerRender(Item item, int meta, String addon)
    {	
    ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName() + addon, "inventory"));
    
    LogHelper.debug("I should be loading the json file for: " + item.getRegistryName() + addon + " and setting metadata: " + meta);
    }
    

  9. Modifing the metadata of the stack, and assigning the different metadata a different model when registered using ModelLoader.setCustomModelResourceLocation(...)

     

    Hmm. That sounded easy until I managed to confuse myself. I was originally using

     

     

    public static void registerRenders() 
    {
    registerRender(testItem);
    }
    
    public static void registerRender(Item item)
    {
    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
    }
    

     

     

    and it could find my original json file just fine, and it showed in game. I tried changing that to take a string to seperate them, making it:

     

     

     

    public static void registerRenders() 
    {
    registerRender(testItem, 0, "Stage0");
    registerRender(testItem, 1, "Stage1");
    registerRender(testItem, 2, "Stage2");
    }
    
    public static void registerRender(Item item, int meta, String addon)
    {
    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, meta, new ModelResourceLocation(item.getRegistryName()+addon, "inventory"));
    }
    

     

     

    And that didn't complain about not being able to find my new json files, but it was broken texture in game.

     

    After switching that to

     

    ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName() + addon, "inventory"));
    

    Now it also can't find my json files.

     

    After remembering to register my event, same problem as above. It doesn't complain that it can't find the json files... ...it just doesn't load the textures in game.

  10. I know that much. As I said (the quick buttons don't seem to be working right now so... improvise) "which is the spawn block in world under onupdate.. taken straight from the vanilla code for melons..."

     

    Line 120 is

    world.setBlock(j1, y, k1, this.block);
    

     

    but I can't even begin to imagine why that could be null.

     

    The stem works fine on it's own... as does the melon block... it's when it tries to spawn a melon that it breaks.. and the code is literally copy pasted from the vanilla code. I don't understand why it's not working.

     

    EDIT: Out of curiosity.. I just deleted that entire class and started over RE copypasta-ing and refactoring variables.... and this time it worked just fine.... I don't even know what was up but thats fixed. That just leaves the particles of my custom food being a weird color.

  11. More custom food errors... but this time only halfway related to the spoiling food... Namely those foods have messed up particles

    So this was interesting to try and snap a picture for but:

     

     

    SR4MtTV.png

     

     

    The food particles don't look anything like ANY of the textures I have registered for this... Is there a easy way to fix or remove them?

     

    and more pressingly: My custom block/stem crops are crashing with:

     

    java.lang.NullPointerException: Exception ticking world
    ...
    at com.Rohzek.food.crop.BlockStem.updateTick(BlockStem.java:120)
    ...
    

     

    which is the spawn block in world under onupdate.. taken straight from the vanilla code for melons... Not sure whats wrong with it?

     

     

    public void updateTick(World world, int x, int y, int z, Random random)
        {
            super.updateTick(world, x, y, z, random);
    
            if (world.getBlockLightValue(x, y + 1, z) >= 9)
            {
                float f = this.func_149875_n(world, x, y, z);
    
                if (random.nextInt((int)(25.0F / f) + 1) == 0)
                {
                    int l = world.getBlockMetadata(x, y, z);
    
                    if (l < 7)
                    {
                        ++l;
                        world.setBlockMetadataWithNotify(x, y, z, l, 2);
                    }
                    else
                    {
                        if (world.getBlock(x - 1, y, z) == this.block)
                        {
                            return;
                        }
    
                        if (world.getBlock(x + 1, y, z) == this.block)
                        {
                            return;
                        }
    
                        if (world.getBlock(x, y, z - 1) == this.block)
                        {
                            return;
                        }
    
                        if (world.getBlock(x, y, z + 1) == this.block)
                        {
                            return;
                        }
    
                        int i1 = random.nextInt(4);
                        int j1 = x;
                        int k1 = z;
    
                        if (i1 == 0)
                        {
                            j1 = x - 1;
                        }
    
                        if (i1 == 1)
                        {
                            ++j1;
                        }
    
                        if (i1 == 2)
                        {
                            k1 = z - 1;
                        }
    
                        if (i1 == 3)
                        {
                            ++k1;
                        }
    
                        Block block = world.getBlock(j1, y - 1, k1);
    
                        if (world.isAirBlock(j1, y, k1) && (block.canSustainPlant(world, j1, y - 1, k1, UP, this) || block == Blocks.dirt || block == Blocks.grass))
                        {
                            world.setBlock(j1, y, k1, this.block);
                        }
                    }
                }
            }
        }
    

     

  12. Hmm. Interesting. I COULD compound things by adding checks to see how long it's been since the update function of the entityitem has ran similar to how I handled the chest..but I'm not sure I care THAT much, at least right now... I guess item frames are free safe storage for my foods then. Thanks. :)

  13. EDIT: I still don't know how to deal with Item Frames.. but my problem my last problem was one number out of place messing the numbers up.

    Anyone have any ideas about how to work with item frames? Do I still have access to the entityItem / the itemstack's nbt or something somehow while it's on an item frame?

×
×
  • Create New...

Important Information

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