• 10

    posted a message on Eldritch Empires - Minecraft Base Defense - now v0.9.1 - added 6 new golems!



    First, I'll explain how it works:
    Getting Started



    Make a collector (recipe below) and right click to turn it on/off. While it's on, a portal will be created in a random location nearby. Attacking creatures will come from the portal and attempt to destroy the collector. It's up to you to make sure they don't do that.

    The collector collects magic essence, which also comes through the portal, so you must have a clear path between the collector and the portal for the collector to work properly. Magic essence is nearly invisible, but if you look carefully, you can notice the sparkles. When the magic essence reaches the collector, it drops a condensed magic essence item.

    You can use the condensed magic essence, to build defensive golems, create items, or combine 9 together to get a diamond.


    Enemies



    They come in 4 varieties, regular Zoblins, Zoblin Bombers, Zoblin Warriors and the much more difficult Zoblin Boss. Make sure to kill bombers quickly, as they can blow up and destroy the collector.

    Rabid Dwarfs
    These come in 3 regular varieties, the normal Rabid Dwarfs, Dwarf Miners and Dwarf Warriors. Miners carry a pickaxe that they use to destroy blocks, so be careful (work in progress). There's also the Dwarven Demolitionist, a boss mob that throws bombs. Destroy them quick before they explode!


    Defense


    There are 3 basic golems that can be upgraded into new forms, the stone archer, stone mage, and stone warrior. Check the recipes section for how to make the blocks that spawn them. A couple other notes, they can take a little while to spawn at first, and if it's killed, just wait a little bit and another one should spawn in its place.

    The golem wand is used to upgrade your defensive golems. While holding the wand, right click on the spawner block (not the golem itself) to see upgrade options.
    Base class upgrade: 5 exp levels + condensed magic essence
    Elite class upgrade: 10 exp levels + required upgrade crystal


    Recipes



    Collector


    Golem Part


    Stone Archer Spawner (requires undamaged bow)


    Stone Warrior Spawner (requires undamaged iron sword)


    Stone Mage Spawner


    Golem Wand


    Portal Focus


    Ice Crystal


    Fire Crystal


    Poison Crystal (those are fermented spider eyes)


    Dark Crystal


    Earth Crystal


    Hero's Crystal

    Disclaimer: I'm still testing this mod, and while it's worked fine for me, I cannot guarantee it wont do something like corrupt your Minecraft save, make you sterile, or blow up your computer. Use it at your own risk and backup any worlds you want to keep.


    It requires Forge 9.11.1.965, and all you've got to do is drop it in your mods folder. It has now been upgraded to 1.6.4, and it should be working for both single player and multi player.

    There is a 1.7 version, though I don't recommend it yet. View the details here, and use at own risk.

    It's also open-source, though I haven't updated this with the newer version yet: GitHub page.

    Change Log


    0.9
    • Reworked the way golems upgrade, and added 6 new types of golems.
    • Enemy waves are now random, and all 9 levels are now available.
    • New mob, zoblin hounds.
    0.8.1
    • Golems now attack all hostile mobs
    0.8
    • enormous rewrite of code, everything should (hopefully) work better and run faster
    • round progress is now stored as block metadata
    • collector now deactivates when its health drops to 0 instead of being destroyed
    • explosions now damage collector instead of destroying it
    • portal focus no longer indestructible
    • golems respawn upon upgrade in creative mode
    • first round spawns faster
    0.7.7
    • made dwarf demolitionist bomb throw rate more predictable
    • waits until closer to throw bombs
    • mobs no longer get stuck together at portal
    • add costs to spawner gui
    • current wave now announced
    • ice crystal no longer creates bombs
    • golem spawners more blast resistant
    • golem spawners now 1/2 block high
    • mobs no longer fall through golem spawners
    • golem spawners no longer require a block underneath
    • golem spawners cannot be placed directly above/below another spawner
    • golems no longer drop items
    0.7.6
    • Golems now cost exp levels and condensed magic essence to upgrade
    • Round now ends when boss is killed
    • Attackers now drop random items, with some very nice rare items
    • Added configuration file
    • Better packet handling
    0.7.5
    • New boss, dwarven demolitionist
    • Golems spawners can now be upgraded
    • New block, portal focus. You can use it to set the location of the portal.
    0.7.2
    • Added Stone Mages & Stone Warriors
    • Added 3 varieties of a new enemy, Rabid Dwarves
    • Stone Archers no longer damage each other or players
    • All attackers can now damage and destroy the collector
    • Added 1 round of rabid dwarf attacks.
    • Many many more changes/tweaks/bug fixes
    0.5.2
    • various bug fixes
    • 3 different levels of zoblin waves
    • new gui for collector
    0.5
    • collector/portal mechanics changed
    • collector must now be activated by right-clicking
    • portal no longer craftable, spawns by itself after activating collector
    • new mob
    • another round of 10 waves, more difficult than before
    • waves reset if deactivated by right-clicking
    • wave number is now saved

    New mod spotlight from BioMasterZap:


    Thanks to TheDiamondMinecart for my second Mod Showcase, note that this is an older version of the mod.

    More Mod Showcases



    My first mod showcase, thanks jackdavid12345! I changed the mechanics of the collector and the portals, but most of it still applies to the most recent version:


    Future Plans

    • More types of enemies/different portals
    • More defensive items
    • Working multiplayer
    • A golem "forge" block and more types of golems
    • Better looking models, textures, & icons
    • More difficult waves of enemies in the end/nether
    • Zoblin dimension, other dimensions...

    I'd like to continue to expand this mod, but I also realize it's an enormous amount of work for a single person. If anybody would like to assist me in creating this, I could use help with coding, modeling, textures... pretty much everything. If you're interested, leave a reply with an example of your work.

    Posted in: WIP Mods
  • 1

    posted a message on Eldritch Empires - Minecraft Base Defense - now v0.9.1 - added 6 new golems!
    I've just released a big update for 1.6.4 that reworks a whole bunch of this mod.
    • The way golem upgrades work has been redone, and 6 new types of golems have been released, each with it's own unique abilities.
    • There's a new type of mob, the zoblin hound, which leaps towards its target.
    • All 9 levels of round strength are open, and the spawns have been randomized.
    Let me know if you find any bugs or mistakes, I've done a bit of testing, but nothing too exhaustive yet.
    Posted in: WIP Mods
  • 44

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    I haven't seen any tutorials on the basics of 1.7.2 yet, so I figured I'd create my own. I'm still learning how 1.7.2 works myself, so please let me know if there's better ways of doing this or if I made an mistakes and I'll adjust the tutorial.

    Also, make sure you're using the latest recommended release for Forge, currently 10.12.0.1024. If you try using earlier version of Forge 1.7, many of the method names will likely not be the same. If you need help setting up your programming environment, that describes the process.

    1. Add new Block and Creative Tab

    First, here's a very basic mod class to begin with:
    package mymod;
    
    import net.minecraft.block.Block;
    import net.minecraft.creativetab.CreativeTabs;
    import cpw.mods.fml.common.Mod;
    import cpw.mods.fml.common.Mod.EventHandler;
    import cpw.mods.fml.common.event.FMLPreInitializationEvent;
    import cpw.mods.fml.common.registry.GameRegistry;
    
    @Mod(modid = MyMod.MODID, version = MyMod.VERSION)
    public class MyMod
    {
    public static final String MODID = "mymod";
    public static final String VERSION = "0.1";
    
    public static Block blockTest;
    
    public static CreativeTabs tabMyMod = new CreativeTabsMyMod("MyMod");
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
    blockTest = new BlockTest().setBlockName("blockTest");
    GameRegistry.registerBlock(blockTest, blockTest.getUnlocalizedName().substring(5));
    }
    }


    You can adjust these two lines to provide a unique Mod ID and a version for your mod. I've been told the Mod ID must be all lowercase letters now.

    public static final String MODID = "mymod";
    public static final String VERSION = "0.1";


    This line declares the block:

    public static Block blockTest;


    This line sets up a new creative tab:

    public static CreativeTabs tabMyMod = new CreativeTabsMyMod("MyMod");


    And these two lines are used to register the block using the unlocalized name "blockTest":

    blockTest = new BlockTest().setBlockName("blockTest");
    GameRegistry.registerBlock(blockTest, blockTest.getUnlocalizedName().substring(5));


    If you're upgrading from previous versions of MC, note that blocks must now be registered inside a FMLPreInitializationEvent, FMLInitializationEvent no longer works.

    Now we need two more classes, one for the block, and one for the creative tab. I'll start with the block:

    package mymod;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.creativetab.CreativeTabs;
    
    public class BlockTest extends Block {
    
    protected BlockTest() {
    super(Material.ground);
    this.setCreativeTab(MyMod.tabMyMod);
    }
    
    }


    This is about as basic as you can get for a block, super(Material.ground); sets the material type for the block and this.setCreativeTab(MyMod.tabMyMod); sets which creative tab that you see the block in.

    Finally, here's the code to set up a creative tab:
    package mymod;
    
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.init.Blocks;
    import net.minecraft.item.Item;
    
    public class CreativeTabsMyMod extends CreativeTabs {
    
    public CreativeTabsMyMod(String tabLabel)
    {
    super(tabLabel);
    }
    
    @Override
    @SideOnly(Side.CLIENT)
    public Item getTabIconItem()
    {
    return Item.getItemFromBlock(Blocks.dirt);
    }
    
    }


    The part you probably want to change is Item.getItemFromBlock(Blocks.dirt). The getTabIconItem() method returns an Item and uses its icon for the creative tab. I wanted to use the dirt block icon, so I used Item.getItemFromBlock() to change the dirt block (Blocks.dirt) into an Item type.

    That's it for now! You may have noticed this mod is missing some rather important things, such as an icon for the block and localized names. I should be adding those to the tutorial later as I discover how to set all that up myself.

    2. Language Localization

    If you try running the mod, you'll notice the block and the creative tab have odd names in game. The block will be called something like tile.blockTest.name, where "blockTest" is the unlocalized name for the block. Because minecraft is translated into many many different languages, the name for the block that's used in the code doesn't use any specific language. You have to add a file to tell MC how to translate unlocalized names into whichever language the user has chosen, a process known as language localization.

    Other tutorials say you're supposed to use different folders for the language files, but there's only one location I've gotten able to work with forge v1024. Within your forge directory navigate to "src\main\resources\" and create a folder named assets. Within this folder create another folder with your Mod ID as the name, and then within that folder, create a folder named "lang". Using the code from the first tutorial, it should look something like this:

    forge-directory\src\main\resources\assets\mymod\lang

    The lang folder is where you'll be putting all your localization files. For instance, I speak US English, so I'll want to create a localization file named "en_US.lang". For other language codes, you can check "forge-directory\eclipse\assets\lang" for a long list of examples. Within the localization file you should have something that looks like this:

    tile.blockTest.name=Test Block
    
    itemGroup.MyMod=My Mod


    tile.blockTest.name uses the unlocalized name of the block we added in the first tutorial, and "Test Block" is the name we want to display in game. itemGroup.MyMod is the unlocalized name of the creative tab, and if you're not sure about a specific unlocalized name, you can always hover your mouse over an object in game and if it hasn't been named yet, it will give you the unlocalized name.

    If you've done everything correctly, you should be able to start the game now and see the new names you've set.

    3. Add a texture to your block

    If you've followed the tutorial so far, your block should have a magenta and black checkered pattern in game. That's the default texture that is set when MC can't find any other texture to use for the block. Setting your own texture is relatively simple, we just have to declare a new variable and override a couple methods from the Block class.

    Update: If you only have a single block texture you want to use, this tutorial is a bit of overkill. To make things much simpler you can use the method setBlockTextureName(MyMod.MODID + ":" + "blockTest") when registering the block, or within your block's class constructor. If you do that, you can skip the rest of this tutorial, which sets you up for using multiple textures with a block. Thanks to Sequiturian for the tip!

    First, in the BlockTest class you want to add:
    @SideOnly(Side.CLIENT)
    protected IIcon blockIcon;

    This creates a variable called blockIcon to store the texture in. Also, notice the @SideOnly(Side.CLIENT). Minecraft separates the client and server, and since the graphics are handled on the client side, you add this line so they're only loaded on the client.

    Next we add this method:
    @SideOnly(Side.CLIENT)
    @Override
    public void registerBlockIcons(IIconRegister p_149651_1_)
    {
    blockIcon = p_149651_1_.registerIcon(MyMod.MODID + ":" + this.getUnlocalizedName().substring(5));
    }

    This registers the texture, and lets the client know where to find the texture. If you're using the code from the tutorial so far, it will use the following location for textures:

    forge-directory\src\main\resources\assets\mymod\textures\blocks

    And it will search for a file named "blockTest.png" in that directory to use as the texture. Note that "mymod" is what I set the mod ID to in the first tutorial, and "blockTest" is the unlocalized name for the block. Finally, we need this last method:

    @SideOnly(Side.CLIENT)
    @Override
    public IIcon getIcon(int p_149691_1_, int p_149691_2_)
    {
    return blockIcon;
    }


    This method returns the actual texture we want to use for the block, which was set in the registerBlockIcons() method. This should be all you need to get block textures working, though this only works properly for very simple blocks. Blocks with different textures per side, and blocks with different textures based upon metadata will not work properly. I believe the two parameters on the getIcon() method will give you the side and the metadata, though I'll save how to use those for another tutorial.

    The class for the block we added should now look something like this:
    package mymod;
    
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.client.renderer.texture.IIconRegister;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.util.IIcon;
    
    public class BlockTest extends Block {
    
    @SideOnly(Side.CLIENT)
    protected IIcon blockIcon;
    
    protected BlockTest() {
    super(Material.ground);
    this.setCreativeTab(MyMod.tabMyMod);
    }
    
    @SideOnly(Side.CLIENT)
    @Override
    public void registerBlockIcons(IIconRegister p_149651_1_)
    {
    blockIcon = p_149651_1_.registerIcon(MyMod.MODID + ":" + this.getUnlocalizedName().substring(5));
    }
    
    @SideOnly(Side.CLIENT)
    @Override
    public IIcon getIcon(int p_149691_1_, int p_149691_2_)
    {
    return blockIcon;
    }
    
    }


    4. Sided block textures

    First, I'm gonna share a quick tip on how to find out on your own how a method works. I want to know what the two parameters on getIcon(int p_149691_1_, int p_149691_2_) do, so I'll use
    System.out.println(p_149691_1_ + " " + p_149691_2_);

    in the getIcon() method to output the values for each parameter to the console in Eclipse. Turns out p_149691_1_ counts from 0 to 5, while p_149691_2_ stays zero. I know the block texture can be set differently for the 6 different sides of the block, and I haven't set the metadata, so that should be zero. It should now be obvious which one I need to use to set sided textures.

    First, I'm going to add a new IIcon object:
    protected IIcon blockIconTop;


    Then add this line in registerBlockIcons():
    blockIconTop = p_149651_1_.registerIcon(MyMod.MODID + ":" + this.getUnlocalizedName().substring(5) + "Top");

    Note that I'm adding '+ "Top"' to the end of the string, this means it will look for blockTestTop.png in the block texture directory.

    Lastly, I need to change the getIcon() method so it returns blockIconTop for the top side of the block. I looked in the BlockGrass class to find that "1" corresponds to that side of a block. Here's my new method, and I've changed the parameters to make it easier to understand:
    @SideOnly(Side.CLIENT)
    @Override
    public IIcon getIcon(int side, int metadata)
    {
    if (side == 1) {
    return blockIconTop;
    } else {
    return blockIcon;
    }
    }


    If you add a texture image named blockTestTop.png to your block texture directory ( forge-directory\src\main\resources\assets\mymod\textures\blocks ), you should now see that texture on the top side of the block when running MC.

    Here's what my full BlockTest class looks like now:
    package mymod;
    
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.client.renderer.texture.IIconRegister;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.util.IIcon;
    
    public class BlockTest extends Block {
    
    @SideOnly(Side.CLIENT)
    protected IIcon blockIcon;
    protected IIcon blockIconTop;
    
    protected BlockTest() {
    super(Material.ground);
    this.setCreativeTab(MyMod.tabMyMod);
    }
    
    @SideOnly(Side.CLIENT)
    @Override
    public void registerBlockIcons(IIconRegister p_149651_1_)
    {
    blockIcon = p_149651_1_.registerIcon(MyMod.MODID + ":" + this.getUnlocalizedName().substring(5));
    blockIconTop = p_149651_1_.registerIcon(MyMod.MODID + ":" + this.getUnlocalizedName().substring(5) + "Top");
    }
    
    @SideOnly(Side.CLIENT)
    @Override
    public IIcon getIcon(int side, int metadata)
    {
    if (side == 1) {
    return blockIconTop;
    } else {
    return blockIcon;
    }
    }
    
    }



    5. Add an item

    If you understood the process of adding a block in the first tutorial, adding a new item should be cake. I'm going to use the same basic mod code I used in the first tutorial, and add this line to declare an object of the Item type named itemTest. It should go right next to where blockTest was declared.
    public static Item itemTest;


    Next I'll add this line inside the preInit() method. You can also just use Item() instead of ItemTest() if you don't want to use a custom class for your new item.
    itemTest = new ItemTest().setUnlocalizedName("itemTest").setTextureName(MyMod.MODID + ":" + "itemTest");

    I've gone over how the unlocalized name works in previous tutorials, so I'll focus upon the setTextureName() method. It takes a string in the following format "ModID:texture-name", which in this case is "mymod:itemTest". This tells minecraft where to look for your textures, "mymod" is the assets directory, and since it's looking for an item texture, its going to search within the "textures/items" directory within "mymod". Within that directory, it's going to look for an image named "itemTest.png", so the full path should be along the lines of forge-directory\src\main\resources\assets\mymod\textures\items\itemTest.png .

    One more line to add to our mod file within the preInit() method:
    GameRegistry.registerItem(itemTest, itemTest.getUnlocalizedName().substring(5));

    This is what registers the item, i.e. the part that adds your item into the game itself. Finally, we need to create a new class file named ItemTest, I kept mine super-simple, all it does is set which creative tab to use.
    package mymod;
    
    import net.minecraft.item.Item;
    
    public class ItemTest extends Item{
    
    protected ItemTest() {
    this.setCreativeTab(MyMod.tabMyMod);
    }
    
    }

    And that's it! You should now have a new item in-game. Here's my full mod class now if you need to refer to it:

    package mymod;
    
    import net.minecraft.block.Block;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.item.Item;
    import cpw.mods.fml.common.Mod;
    import cpw.mods.fml.common.Mod.EventHandler;
    import cpw.mods.fml.common.event.FMLPreInitializationEvent;
    import cpw.mods.fml.common.registry.GameRegistry;
    
    @Mod(modid = MyMod.MODID, version = MyMod.VERSION)
    public class MyMod
    {
    public static final String MODID = "mymod";
    public static final String VERSION = "0.1";
    
    public static Block blockTest;
    public static Item itemTest;
    
    public static CreativeTabs tabMyMod = new CreativeTabsMyMod("MyMod");
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
    blockTest = new BlockTest().setBlockName("blockTest");
    itemTest = new ItemTest().setUnlocalizedName("itemTest").setTextureName(MyMod.MODID + ":" + "itemTest");
    
    GameRegistry.registerBlock(blockTest, blockTest.getUnlocalizedName().substring(5));
    GameRegistry.registerItem(itemTest, itemTest.getUnlocalizedName().substring(5));
    
    }
    }


    Whoops, I seem to have forgotten something important that I covered in a previous tutorial, notice what it is? When I load up the game, my item is named item.itemTest.name, the name hasn't been localized! No worries, I just need to add this line to my language localization file: item.itemTest.name=Item Test


    6. Add an entity

    It takes a few lines of code to add an entity, and if you've got a lot of entities it can be a pain to write out the code over and over again. To streamline the process, I use a method to take care of all the repetitive work which I've inserted into my mod class:
    public static void registerEntity(Class entityClass, String name)
    {
    int entityID = EntityRegistry.findGlobalUniqueEntityId();
    long seed = name.hashCode();
    Random rand = new Random(seed);
    int primaryColor = rand.nextInt() * 16777215;
    int secondaryColor = rand.nextInt() * 16777215;
    
    EntityRegistry.registerGlobalEntityID(entityClass, name, entityID);
    EntityRegistry.registerModEntity(entityClass, name, entityID, instance, 64, 1, true);
    EntityList.entityEggs.put(Integer.valueOf(entityID), new EntityList.EntityEggInfo(entityID, primaryColor, secondaryColor));
    }

    The first line within registerEntity() is to get a unique ID for the entity. The next four lines generate random colors for the spawn egg using the entity's name as a random seed. If you want to set colors yourself, you could easily adjust the method to take the primary and secondary colors as method parameters.

    EntityRegistry.registerGlobalEntityID(entityClass, name, entityID);
    EntityRegistry.registerModEntity(entityClass, name, entityID, instance, 64, 1, true);
    EntityList.entityEggs.put(Integer.valueOf(entityID), new EntityList.EntityEggInfo(entityID, primaryColor, secondaryColor));

    These lines register the entity ID, register the entity itself, and add a spawn egg respectively. It's mostly the same as MC 1.6, though I had to change EntityEggInfo to EntityList.EntityEggInfo. You may have noticed we haven't declared the instance variable yet, so let's add this line to our mod class. Put it near the top, but underneath the MODID string declaration.
    @Instance(MODID)
    public static MyMod instance;

    One more thing the mod class needs, and that's to actually call the method we just created. Put this line within the preInit() method:
    registerEntity(EntityTest.class, "entityTest");

    Okay, now we need to make the EntityTest class that I just referred to for our entity. Here's some very basic code that's simplified to the point of not really being practical:
    package mymod;
    
    import net.minecraft.entity.monster.EntityMob;
    import net.minecraft.world.World;
    
    public class EntityTest extends EntityMob{
    
    public EntityTest(World par1World) {
    super(par1World);
    }
    
    }

    This class extends EntityMob, which are the hostile monster types of entities. EntityCreature, EntityAnimal, and EntityLiving are all examples of other entity types that you can extend.

    Finally, we give a localized name to our new entity by putting this into our language localization file:
    entity.entityTest.name=Entity Test

    That should be it! If you start minecraft, you should see a new spawn egg under the Miscellaneous creative tab. Using it should create a retarded white box within the game. Not very useful, but not bad to begin with! I'll add more tutorials about making entities smarter and more attractive.

    7. Give entity a model

    If you're not very comfortable coding Java, you may want to stick to easier things like blocks and items. These tutorials are going to start getting a bit more complicated now.

    If you want to mod Minecraft properly, you have to understand how the client-server model works. All the rendering, the parts of the code that display graphics, happen on the client side. This isn't something the server needs to deal with at all. To separate the client and server code we're now going to create proxies, and then use the client proxy to give a proper model to our entity.

    First, you'll need this in your main mod class:
    @SidedProxy(clientSide="mymod.proxy.ClientProxy", serverSide="mymod.proxy.CommonProxy")
    public static CommonProxy proxy;


    This tells Forge which classes we want to use for the client and server proxies. Notice it refers to a new java package, "mymod.proxy" so go ahead and create that now. Next create the server proxy class, CommonProxy, and paste this code inside:
    package mymod.proxy;
    
    public class CommonProxy {
    
    public void registerRenderers() {
    // Nothing here as the server doesn't render graphics or entities!
    }
    }

    Not much there since we don't need to do anything with the server side at the moment. Next create a new class named ClientProxy and paste this code inside:
    package mymod.proxy;
    
    import net.minecraft.client.model.ModelBiped;
    import mymod.EntityTest;
    import mymod.RenderTest;
    import cpw.mods.fml.client.registry.RenderingRegistry;
    
    public class ClientProxy extends CommonProxy{
    
    @Override
    public void registerRenderers() {
    RenderingRegistry.registerEntityRenderingHandler(EntityTest.class, new RenderTest(new ModelBiped(), 0.5F));
    
    }
    }


    The RenderingRegistry.registerEntityRenderingHandler() method tells MC how to render your new entity. The RenderTest class will be used to render EntityTest entities and it will use the ModelBiped class for the model. ModelBiped is the basic player model. Also, the float that's the second parameter in RenderTest determines the shadow size.

    Now we'll need to add a call to registerRenderers() within our main mod class. I put this line at the end of the preInit() method:
    proxy.registerRenderers();


    Next, create the RenderTest class, and paste this code inside:
    package mymod;
    
    import net.minecraft.client.model.ModelBiped;
    import net.minecraft.client.renderer.entity.RenderBiped;
    import net.minecraft.entity.Entity;
    import net.minecraft.util.ResourceLocation;
    
    public class RenderTest extends RenderBiped {
    
    private static final ResourceLocation textureLocation = new ResourceLocation(MyMod.MODID + ":" + "textures/models/entityTest.png");
    
    public RenderTest(ModelBiped model, float shadowSize) {
    super(model, shadowSize);
    }
    
    @Override
    protected ResourceLocation getEntityTexture(Entity par1Entity)
    {
    return textureLocation;
    }
    }

    The class constructor is simple enough, we just pass the parameters on to the RenderBiped class, the superclass of RenderTest. The rest of this code is used to set the texture, getEntityTexture() returns textureLocation, which *gasp* holds the location of the texture. We set it similar to the same way we set block and item textures, but we use a ResourceLocation type and I added some more information on what directory to find the texture in.

    Since I'm using the same model the player uses, any player skin should work fine as a texture for my entity. I'm just testing things out, so I'm going to use the Steve skin, which will go in the location we set using ResourceLocation(MyMod.MODID + ":" + "textures/models/entityTest.png") . If you haven't tweaked your MODID, the path to the texture should be something like this: forge-directory\src\main\resources\assets\mymod\textures\models\entityTest.png

    And that should be it, if you start minecraft and spawn the entity, it should now be using the basic biped model with the Steve skin.

    8. Entity attributes and AI

    If you used the previous tutorials to create an entity, you may have noticed that when you spawn it, it moves painfully slow. We need to set entity attributes, so go ahead and add this code to your entity's class:
    @Override
    protected void applyEntityAttributes()
    {
    	 super.applyEntityAttributes();
    this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
    this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D);
    this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(0.0D);
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D);
    this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(2.0D);
    }

    This code should be fairly self-explanatory, you get the attribute, for instance maxHealth, and then use setBaseValue() to set the value. I should explain knockbackRestistance some, which ranges from 0.0D to 1.0D (the D stands for double, a primitive data type). 0.0D means 0% knockback resistance, so the entity will be knocked back every hit. 1.0D means 100% knockback resistance, so the entity will never be knocked back.

    An important thing to understand abbout attributes is that they're saved per entity. This means you can do things like set them to random values or even alter an entity's attributes after it's been spawned, though I wont go in to how to do that here.

    After adding attributes, it may be that you're happy with the way your entity behaves, and in that case there's no reason to add any "advanced" artifical intelligence (AI). However, if you do want more control over your entity's behavior you'll need to add this method:
    public boolean isAIEnabled()
    {
    	 return true;
    }

    Now this method by itself will just make your entity stand there and stare straight forward. When you've got AI enabled, you have to tell your entity specifically how to behave. We'll do that by adding AI tasks to your entity's class constructor. Here's what I used:
    this.tasks.addTask(1, new EntityAISwimming(this));
    this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false));
    this.tasks.addTask(3, new EntityAIWander(this, 1.0D));
    this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
    this.tasks.addTask(5, new EntityAILookIdle(this));
    
    this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
    this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));

    The numbers that are the first parameter of the addTask method determine the priority of the task. We put EntityAISwimming as 1, since we don't want our entity to drown in water. The EntityAIAttackOnCollide is the basic attack type that mobs like zombies and spiders use. EntityAIWander tells the mob to wander around when it's not attacking. I'll let you figure out what EntityAIWatchClosest does, and EntityAILookIdle makes the mob look around when it's just standing there.

    Then there's the target tasks, which lets the entity know how to choose attack targets. EntityAIHurtByTarget will target any mob that does damage to our entity, and EntityAINearestAttackableTarget will target any nearby entity that matches the second parameter, in this case EntityPlayer.class.

    That should be it, if you run the game your entity should now behave like a regular mob. One thing to be careful about is any mobs that were created in your game before you changed attributes around. You'll have to spawn new entities for them to use the new attributes you set.

    Other 1.7.2 tutorials

    Here's some other tutorials to check out:
    1. [1.7.2][1.6.4] EventHandler and IExtendedEntityProperties - coolAlias
    2. [1.7.2][1.6.4] Custom Inventories in Items and Players - coolAlias
    3. Netty Packet Handling - Sirgingalot - (learn to send packets between the client & server)
    4. Basic Blocks - Havvy - (more information on Blocks than this tutorial)
    5. Wuppy's 1.7 Tutorials

    Happy modding!
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from Beastplayer102

    I was wondering, how you would make an item into Armor, weapons, etc?


    For a new sword, you can try extending the ItemSword class. I believe you have to override this method to set the damage:
        public float func_150931_i()
        {
    	    return field_150933_b.getDamageVsEntity();
        }

    I'm probably not going to cover armor or weapons with my tutorials. Hopefully someone else will add their own, though you may be able to use tutorials for 1.5 and 1.6 as I don't believe much has changed in the armor and weapon code.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from white_nrdy

    is it the same for texturing items, I am having some problems texturing a food I made, it has the correct name and everything, but the texture doesn't work o/

    ^^that is one of my food classes, i replaced the "blockIcon" with itemIcon but that didn't work :(


    I actually just added a tutorial on how to do this while you were writing your comment. =)

    I tried adding item textures a few different ways, but the only thing that worked for me was using .setTextureName() during PreInitialization. Here's the code I used:

    itemTest = new ItemTest().setUnlocalizedName("itemTest").setTextureName(MyMod.MODID + ":" + "itemTest");
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from Phase_Saber

    Totally amazing! Can't wait for more!

    Also, where did you get this information? I've searched all over the interwebs and I couldn't find a thing!


    It's been a combination of what I already knew about modding 1.5 and 1.6, searching the internet, trial and error, plus digging through the code. A lot of it I've had to figure out myself. Some of the earlier 1.7 tutorials were a good start, though you usually have to modify them some to get working.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from navybofus

    P.S. Great job on the tutorials. Thanks for taking my request. I'll have others shortly :) Also, would you want to post a few other snippet tutorials that I've figured out by bumbling around? I can post the code and you can do the tutorial stuffs ;)

    EDIT: Got one, World Gen. Examples of Ores and Plants. Hey, some ppl need to generate plants. lol


    Sure! I'd love to see more examples of 1.7.2 code, there's a whole lot I'm still learning myself. I'm not sure how much I'll be getting into the world gen aspects for this tutorial though. My current plan is to do block metadata, tile entities, mob entities, item creation and packet handling tutorials.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from white_nrdy

    Hey, is the localization file a class in eclipse, or like a notepad file, do we have to write anything inside of the file?...I am confused, I am also new to modding. This tutorial is AWESOME!


    It's "like a notepad file". If you're using windows, you can create a new text document, then rename it to en_US.lang. Make sure you've set things up to not hide file extensions, or it will still be a text file. You must put the names you want your custom blocks, items, entities and creative tab to use inside that file, or they'll be named things like tile.blockTest.name within the game.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Just added the 3rd part of the tutorial, adding textures to you block.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.2] Forge | Add new Block, Item, Entity, AI, Creative tab, Language localization, Block textures, Side textures
    Quote from navybofus

    please let the next topic be about adding textures to blocks. I've tried everything. I know my textures are in the correct directory, but I'm sure that my String isn't saying what I think it's saying.

    Also, what's with this substring(5) stuff that I've been seeing. After looking it up it talks about replacing text in strings?


    When you use blockTest.getUnlocalizedName() I believe it returns the string tile.blockTest . Using the substring(5) method trims the first 5 characters in the string so you just get the unlocalized named without the "tile." part.

    And textures for blocks is what I plan on doing for my next tutorial, just as soon as I figure out how to get it working myself.
    Posted in: Mapping and Modding Tutorials
  • To post a comment, please .