Hey guys, wanted to give back to the community this time, usually I just leech around, but this took me some time to get working so I wanted to provide aid that I would've wanted.
Anyway, before I get started, I'm going to assume that so far you know some basic java, have a forge modding environment, a base mod class, common and client proxies, as well as a bow class that already works as far as having a registered icons that transition as the bow is pulled, shooting arrows, and that sort of thing. This tutorial is ONLY going to cover the third person of the bow.
Firstly, you'll need to make yourself a custom item renderer for bows. If you want to, simply make a new class that implements IItemRenderer, and add the unimplemented methods, then you can look through the posted code and add what's needed. However, if you're lazy like me, you can just copy paste the code.
NOTE: Much of this code is from a helpful user named SanAndreasP on Minecraft Forge. He had the original solution for 1.5.2, I simply adapted it to 1.6.2. I did NOT ask him if I could share it, but I'm assuming he won't mind in the good favor of friendly modding. If for any reason there are problems with this, just let me know. I DO NOT TAKE CREDIT FOR THIS CODE.
THANKS:
-SanAndreasP for the original code
-me for updating to 1.6.2
-mathiasrocker for updating to 1.6.4
Assuming you don't have one, make a new class (I called mine BowRenderer) and copy this code:
package naoticon.attainablesplus.common;
import java.lang.reflect.Method;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.entity.EntityLiving;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
public class BowRenderer implements IItemRenderer {
private RenderManager renderManager;
private Minecraft mc;
private TextureManager texturemanager;
public BowRenderer() {
this.renderManager = RenderManager.instance;
this.mc = Minecraft.getMinecraft();
this.texturemanager = this.mc.getTextureManager();
}
@Override
//HandleRenderType lets forge know if it will render the item in the requested view.
public boolean handleRenderType(ItemStack item, ItemRenderType type) {
//You can remove everything after "EQUIPPED" if you only want this class to render the third person item.
return type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON;
}
@Override
//RenderHelpers I don't fully understand, I'd assume they are modifiers, but I've never looked into it.
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
return false;
}
@Override
//This function decides what to do in rendering an item, whether it's first or third person.
//Credit to SanAndreasP on minecraftforge forums for this code.
public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
EntityClientPlayerMP entity = (EntityClientPlayerMP)data[1];
ItemRenderer irInstance = this.mc.entityRenderer.itemRenderer;
GL11.glPopMatrix(); // prevents Forge from pre-translating the item
if(type == ItemRenderType.EQUIPPED_FIRST_PERSON) {
this.renderItem(entity, item, 0);
} else {
GL11.glPushMatrix();
// contra-translate the item from it's standard translation
// also apply some more scale or else the bow is tiny
float f2 = 3F - (1F/3F);
GL11.glRotatef(-20.0F, 0.0F, 0.0F, 1.0F);
GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(-60.0F, 0.0F, 0.0F, 1.0F);
GL11.glScalef(f2, f2, f2);
GL11.glTranslatef(-0.25F, -0.1875F, 0.1875F);
// render the item as 'real' bow
//This is pulled from RenderBiped
float f3 = 0.625F;
GL11.glTranslatef(0.0F, 0.125F, 0.3125F);
GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F);
GL11.glScalef(f3, -f3, f3);
GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
this.renderItem(entity, item, 0);
GL11.glPopMatrix();
}
GL11.glPushMatrix(); // prevents GL Underflow errors
}
//This actually renders an Icon to be worked with.
//All of this code is directly pulled from ItemRenderer.class
private void renderItem(EntityClientPlayerMP par1EntityLiving, ItemStack par2ItemStack, int par3) {
{
//If you for whatever reason aren't registering icons with iconRegister, I'm assuming you'll need to change the code below.
Icon icon = par1EntityLiving.getItemIcon(par2ItemStack, par3);
if (icon == null)
{
GL11.glPopMatrix();
return;
}
texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber()));
Tessellator tessellator = Tessellator.instance;
float f = icon.getMinU();
float f1 = icon.getMaxU();
float f2 = icon.getMinV();
float f3 = icon.getMaxV();
float f4 = 0.0F;
float f5 = 0.3F;
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glTranslatef(-f4, -f5, 0.0F);
float f6 = 1.5F;
GL11.glScalef(f6, f6, f6);
GL11.glRotatef(50.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(335.0F, 0.0F, 0.0F, 1.0F);
GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F);
ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, icon.getOriginX(), icon.getOriginY(), 0.0625F);
//This checks for enchantments.
if (par2ItemStack.hasEffect(par3))
{
GL11.glDepthFunc(GL11.GL_EQUAL);
GL11.glDisable(GL11.GL_LIGHTING);
texturemanager.bindTexture(new ResourceLocation("textures/misc/enchanted_item_glint.png"));
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
float f7 = 0.76F;
GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F);
GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glPushMatrix();
float f8 = 0.125F;
GL11.glScalef(f8, f8, f8);
float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F;
GL11.glTranslatef(f9, 0.0F, 0.0F);
GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F);
ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F);
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glScalef(f8, f8, f8);
f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F;
GL11.glTranslatef(-f9, 0.0F, 0.0F);
GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F);
ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDepthFunc(GL11.GL_LEQUAL);
}
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
}
}
}
Obviously, you'll need to change the package declarations as well as the name, depending on your setup.
I put a couple of coments in there to try and explain what does what and where, any questions just post in the comments and I'll do my best to answer them.
Now, to register this renderer, you'll need to add this line to the registerRenderers in your ClientProxy:
MinecraftForgeClient.registerItemRenderer(AttainablesPlus.ItemNaniteBow.itemID, new BowRenderer());
Or, if you don't have a registerRenderers function, just add this block:
@Override
public void registerRenderers() {
MinecraftForgeClient.registerItemRenderer(AttainablesPlus.ItemNaniteBow.itemID, new BowRenderer());
}
Again, you need to change the item to whatever your bow is and the function to your renderer class's name. Also keep in mind that you can register multiple items to one renderer, so if you have multiple bows, just copy paste that line and change the name.
And finally, we need to call the registerRenderers method inside our main mod class. This is done in any initialization event, but must be done AFTER your items are registered. It will look something like this when done:
@EventHandler
public void InitAttainablesPlus(FMLInitializationEvent event){ //The main initialization method
AttPlusItems.init();
AttPlusItems.addNames();
AttPlusBlocks.init();
AttPlusBlocks.addNames();
//Note that the above methods contain the code to define my items, I simply moved them to their own files for organization.
proxy.registerRenderers();
}
And that should do it. It is pretty late as I'm writing this so if anything fails to work, let me know and I'll double check it. Hope that this helps some of you.
Thank you for the feedback! I apologize that this is such a late reply and hope that you still read it. I apparently forgot to make the needed changes to the OP, my bad. The error is caused by calling registerRenderers before any of your items are defined. Move the registerRenderers to any location after your items and blocks are registered, for instance mine looks like this:
@EventHandler
public void PreInit(FMLPreInitializationEvent event) {
ConfigManager.init(event.getSuggestedConfigurationFile());
}
@EventHandler
public void InitAttainablesPlus(FMLInitializationEvent event){ //The main initialization method
AttPlusItems.init();
AttPlusItems.addNames();
AttPlusBlocks.init();
AttPlusBlocks.addNames();
proxy.registerRenderers();
}
Note that my items and blocks are defined and their IDs assigned in the classes mentioned above. Sorry that I forgot to mention this error, I hope that you will check this. I'll edit the OP now.
So it's all working now? Cool. I'm glad I could help haha it was very frustrating, Really this should be a custom item renderer tutorial, but I figured since most people wouldn't search for that to just leave it as is. I won't complain if you want to credit me and the original author, although really I didn't do much work at all.
Awesome. I would try to update the code myself, but I haven't had time to work on any programming projects recently due to school. Thanks for taking the initiative to update it!
I figured something close to rendering the bow properly (1.6.4mc)
just add in the bow class
this.bFull3D = true;
under the
this.setMaxDamage(384); it isn't exact but do-able
This is one way to do it, however the bFull3D code is for items like tools. It doesn't render it the same as a bow, and there is quite a noticeable difference. I personally am a bit too OCD to settle for it
Anyway, before I get started, I'm going to assume that so far you know some basic java, have a forge modding environment, a base mod class, common and client proxies, as well as a bow class that already works as far as having a registered icons that transition as the bow is pulled, shooting arrows, and that sort of thing. This tutorial is ONLY going to cover the third person of the bow.
Firstly, you'll need to make yourself a custom item renderer for bows. If you want to, simply make a new class that implements IItemRenderer, and add the unimplemented methods, then you can look through the posted code and add what's needed. However, if you're lazy like me, you can just copy paste the code.
NOTE: Much of this code is from a helpful user named SanAndreasP on Minecraft Forge. He had the original solution for 1.5.2, I simply adapted it to 1.6.2. I did NOT ask him if I could share it, but I'm assuming he won't mind in the good favor of friendly modding. If for any reason there are problems with this, just let me know. I DO NOT TAKE CREDIT FOR THIS CODE.
THANKS:
-SanAndreasP for the original code
-me for updating to 1.6.2
-mathiasrocker for updating to 1.6.4
Assuming you don't have one, make a new class (I called mine BowRenderer) and copy this code:
I put a couple of coments in there to try and explain what does what and where, any questions just post in the comments and I'll do my best to answer them.
Now, to register this renderer, you'll need to add this line to the registerRenderers in your ClientProxy:
Or, if you don't have a registerRenderers function, just add this block:
And finally, we need to call the registerRenderers method inside our main mod class. This is done in any initialization event, but must be done AFTER your items are registered. It will look something like this when done:
And that should do it. It is pretty late as I'm writing this so if anything fails to work, let me know and I'll double check it. Hope that this helps some of you.
Note that my items and blocks are defined and their IDs assigned in the classes mentioned above. Sorry that I forgot to mention this error, I hope that you will check this. I'll edit the OP now.
just add in the bow class
this.bFull3D = true;
under the
this.setMaxDamage(384);
it isn't exact but do-able
This is one way to do it, however the bFull3D code is for items like tools. It doesn't render it the same as a bow, and there is quite a noticeable difference. I personally am a bit too OCD to settle for it
Thanks! I'm glad that I could help.
It's all the same code but instead of
it is
And
is
And last
is
Thanks for posting an update, I haven't had time to look work on any mods with school. I'll update the OP.
How do I change this to fit my mod?
how do i make it shoot wither skulls or ghast fireballs?
I am just a viewer