Creating a Gun

Making a gun is not very hard, and does not require extensive knowledge in modding. I will be making an EMP gun, that destroys redstone equipments and turns redstone blocks into stone blocks in a 4-block radius. It won’t have a durability value for now, though.

First, we create the gun item itself. Just like creating a normal item, except you need to add a few extra stuff. The texture I used is this:

public class EMPGun extends Item
{
    public EMPGun()
    {
        setCreativeTab(CreativeTabs.tabCombat);
        setMaxStackSize(1);
        setMaxDamage(0);
    }

    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
    {
        if (player.capabilities.isCreativeMode || player.inventory.consumeInventoryItem(ModItems.emp))
        {
            player.swingItem();
            world.playSoundAtEntity(player, YourMod.MODID + ":emp_gun", 0.5F, 1.0F);
            if (!world.isRemote)
            {
                world.spawnEntityInWorld(new EntityEMP(world, player));
            }
        }
        return itemStack;
    }
}

What I added is the method onItemRightClick, which is self explanatory. It goes like this: If the player is in creative mode, or the player has a projectile (in this case an EMP), swing the item, play a custom sound, and spawn the projectile entity.

This code will give you errors, but that’s because we haven’t made the EMP item and the EMP projectile. The playSoundAtEntity method accepts a string parameter corresponding to the sound location. It accepts OGG sound files. If written like so, this method will get “emp_gun.ogg” from “assets/yourmodid/sounds/” folder. For this to work, you need to create a sounds.json file in your “assets/yourmodid/” folder. In it, add these:

{
"emp_gun": {"category": "master","sounds": [{"name": "emp_gun","stream": false}]}
}

You can download my sound file here.

Okay, now let’s create an item for the projectile. You don’t have to do this if you have another system for storing the projectiles, but for now, let’s make it similar to how a bow works. It does not have to do anything, so I won’t cover this part. If you once again want to use my textures, here it is:

Don’t forget to register these two items in your ModItems class!

Right. With that we are done fiddling with items. Now let’s make the projectile, which is actually an entity. Luckily, there exists a class just right for our needs, that we can extend from, and it is EntityThrowable. So let’s extend from that, and add a function on our own.

public class EntityEMP extends EntityThrowable
{
    public static final float explosionPower = 0.75F
    public static final int empRadius = 4;

    public EntityEMP(World world)
    {
        super(world);
    }

    public EntityEMP(World world, EntityLivingBase entity)
    {
        super(world, entity);
    }

    private void explode()
    {
        int bx = (int)posX;
        int by = (int)posY;
        int bz = (int)posZ;
        worldObj.createExplosion(this, posX, posY, posZ, 0.75F, true);

        for (int x = bx - empRadius; x <= empRadius; x++)
        {
            for (int y = by - empRadius; y <= by + empRadius; y++)
            {
                for (int z = bz - empRadius; z <= bz + empRadius; z++)
                {
                    Block block = worldObj.getBlock(x, y, z);
                    if (block == Blocks.redstone_wire || block instanceof BlockRedstoneDiode)
                    {
                        block.dropBlockAsItem(worldObj, x, y, z, worldObj.getBlockMetadata(x, y, z), 0);
                        worldObj.setBlockToAir(x, y, z);
                    }
                    if (block == Blocks.redstone_block)
                    {
                        worldObj.setBlock(x, y, z, Blocks.stone);
                    }
                }
            }
        }
        setDead();
    }
    @Override
    public void onUpdate()
    {
        super.onUpdate();
        if (ticksExisted > 20)
        {
            explode();
        }

        for (int i = 0; i < 10; i++)
        {
            double x = (double)(rand.nextInt(10) - 5) / 8.0D;
            double y = (double)(rand.nextInt(10) - 5) / 8.0D;
            double z = (double)(rand.nextInt(10) - 5) / 8.0D;
            worldObj.spawnParticle("fireworksSpark", posX, posY, posZ, x, y, z);
        }
    }

    @Override
    protected float getGravityVelocity()
    {
        return 0.005F;
    }

    @Override
    public void onImpact(MovingObjectPosition movingObjectPosition)
    {
        explode();
    }
}

Alright. Explanation time! We have set two final variables, explosionPower and empRadius, the explosionPower is how big the projectile will detonate on impact. The empRadius variable is how big the area to destroy redstone stuff. After three required constructors that does nothing special, we have added a few methods.

First, a custom method to explode our projectile. What this does is, first it creates an explosion (you don’t say?), and then it checks a 4-block radius for redstone stuff and drops it as items, and replaces redstone blocks with stone. Then, it kills the projectile, because normally stuff dies when exploding, right? Right.

Now, onto the onUpdate() method. This method is called every tick to update the entity. Remember to add super.onUpdate(); because it has some stuff it needs to do and by overriding it we won’t run the original code and will break things, unless of course we call it with super(). The next line auto-explodes the projectile if it travels more than 20 game ticks, i.e. one second. You can change or remove this to your liking, but you wouldn’t like entities flying forever to unloaded chunks. Also, we add fancy particle effects to the projectile.

And then, getGravityVelocity(). This changes the normal value of 0.03F to 0.005F, so our projectile don’t fall down as quickly.

Last one is the onImpact(), which is called when… you guessed it… it crashes into something. In our case, we want it to explode.

Now, register the entity with this line on your main class:

EntityRegistry.registerModEntity(EntityEMP.class, "EMP", 0, this, 64, 10, true);

Just for fun, I’ll add a custom model to my projectile entity. The model is made with Techne and slight edited, it’s this:

public class ModelEMP extends ModelBase
{
    ModelRenderer Shape1;
    ModelRenderer Shape2;
    ModelRenderer Shape3;
    ModelRenderer Shape4;

    public ModelEMP()
    {
        textureWidth = 64;
        textureHeight = 32;

        Shape1 = new ModelRenderer(this, 0, 0);
        Shape1.addBox(0F, 0F, 0F, 4, 4, 4);
        Shape1.setRotationPoint(-2F, 19F, -2F);
        Shape1.setTextureSize(64, 32);
        Shape1.mirror = true;
        setRotation(Shape1, 0F, 0F, 0F);
        Shape2 = new ModelRenderer(this, 0, 0);
        Shape2.addBox(0F, 0F, 0F, 2, 6, 2);
        Shape2.setRotationPoint(-1F, 18F, -1F);
        Shape2.setTextureSize(64, 32);
        Shape2.mirror = true;
        setRotation(Shape2, 0F, 0F, 0F);
        Shape3 = new ModelRenderer(this, 0, 0);
        Shape3.addBox(0F, 0F, 0F, 6, 2, 2);
        Shape3.setRotationPoint(-3F, 20F, -1F);
        Shape3.setTextureSize(64, 32);
        Shape3.mirror = true;
        setRotation(Shape3, 0F, 0F, 0F);
        Shape4 = new ModelRenderer(this, 0, 0);
        Shape4.addBox(0F, 0F, 0F, 2, 2, 6);
        Shape4.setRotationPoint(-1F, 20F, -3F);
        Shape4.setTextureSize(64, 32);
        Shape4.mirror = true;
        setRotation(Shape4, 0F, 0F, 0F);
    }

    public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
    {
        super.render(entity, f, f1, f2, f3, f4, f5);
        setRotationAngles(f, f1, f2, f3, f4, f5, entity);
        Shape1.render(f5);
        Shape2.render(f5);
        Shape3.render(f5);
        Shape4.render(f5);
    }

    private void setRotation(ModelRenderer model, float x, float y, float z)
    {
        model.rotateAngleX = x;
        model.rotateAngleY = y;
        model.rotateAngleZ = z;
    }

    public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
    {
        super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
    }
}

Ideally this should be put in a seperate package, mine is the “model” package. Now, we should make a rendering class, and register a texture to the model with the following class. With this code, the texture should be put in assets/yourmodid/textures/entity/” folder. This is my texture:

public class RenderEMP extends Render
{
    private static final ResourceLocation texture = new ResourceLocation(UtilityGuns.MODID, "textures/entity/emp.png");
    private ModelBase model;

    public RenderEMP()
    {
        model = new ModelEMP();
    }

    @Override
    public ResourceLocation getEntityTexture(Entity entity)
    {
        return texture;
    }

    @Override
    public void doRender(Entity entity, double x, double y, double z, float yaw, float partialTick)
    {
        GL11.glPushMatrix();
        bindTexture(texture);
        GL11.glTranslated(x, y - 1.25D, z);
        model.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
        GL11.glPopMatrix();
    }
}

Now in your ClientProxy add this line to register the class you just made:

RenderingRegistry.registerEntityRenderingHandler(EntityEMP.class, new RenderEMP());

And we’re done! Congratulations, you made your own gun!

4 thoughts on “Creating a Gun

  1. Pirate Cody August 25, 2015 / 1:52 PM

    Great tutorial

    Like

  2. ANONYMOUS March 27, 2016 / 5:05 PM

    On the top…

    //—————————-
    public class EMPGun extends Item
    {
    setCreativeTab(CreativeTabs.tabCombat);
    setMaxStackSize(1);
    setMaxDamage(0);
    }

    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
    {
    if (player.capabilities.isCreativeMode || player.inventory.consumeInventoryItem(ModItems.emp))
    {
    player.swingItem();
    world.playSoundAtEntity(player, YourMod.MODID + “:emp_gun”, 0.5F, 1.0F);
    if (!world.isRemote)
    {
    world.spawnEntityInWorld(new EntityEMP(world, player));
    }
    }
    return itemStack;
    }

    //—————————-
    is wrong!

    You can’t write codes directly in the class, and outside it.
    I think this is your code.

    public class EMPGun extends Item {
    public EMPGun() {
    setCreativeTab(CreativeTabs.tabCombat);
    setMaxStackSize(1);
    setMaxDamage(0);
    }

    @Override public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
    if (player.capabilities.isCreativeMode || player.inventory.consumeInventoryItem(ModItems.emp)) {
    player.swingItem();
    world.playSoundAtEntity(player, YourMod.MODID + “:emp_gun”, 0.5F, 1.0F);
    if (!world.isRemote) {
    world.spawnEntityInWorld(new EntityEMP(world, player));
    }
    }
    return itemStack;
    }
    }

    Like

    • Emx2000 March 27, 2016 / 5:42 PM

      I must’ve mistyped. I’ll look into it ASAP when I reach my PC. Thanks for pointing it out!

      EDIT: Fixed!

      Like

Leave a comment