First off, I had trouble finding a nice example for custom arrows. I had to look at vanilla classes and may have butchered some stuff. I am pretty new to Forge in general too (You can probably get this from my question). I am making a mod that implements Jade and some other cool stuff I was thinking of. It is a crystal that naturally generates in caves and I made blocks for it slabs, some cool recipes to go with it, etc. Now I wanted to make a Jade Arrow. The Jade Arrow is just a "sharper" arrow. I set the arrowHit() to deal excess damage to the LivingEntity that was hit. For some reason when I shoot my Jade Arrow the game crashes.
RegistryHandler:
package com.chuck.jademod.util;
import com.chuck.jademod.Jade;
import com.chuck.jademod.blocks.*;
import com.chuck.jademod.entities.EntityJadeArrow;
import com.chuck.jademod.items.ItemBase;
import com.chuck.jademod.items.JadeArrow;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.StairsBlock;
import net.minecraft.block.WallBlock;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.item.*;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import java.rmi.registry.RegistryHandler;
import static com.chuck.jademod.Jade.MOD_ID;
public class RegisteryHandler {
public static DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID);
public static DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MOD_ID);
public static DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITIES, MOD_ID);
public static void init(){
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());
}
// items
public static final RegistryObject<Item> JADE_SHARD = ITEMS.register("jade_shard", ItemBase::new );
public static final RegistryObject<Item> JADE_ARROW = ITEMS.register("jade_arrow", JadeArrow::new);
// Blocks
public static final RegistryObject<Block> JADE_CRYSTAL_BLOCK = BLOCKS.register("jade_crystal_block", JadeCrystalBlock::new);
public static final RegistryObject<Block> JADE_ORE_BLOCK = BLOCKS.register("jade_ore_block", JadeOreBlock::new);
public static final RegistryObject<Block> JADE_BLOCK = BLOCKS.register("jade_block", JadeBlock::new);
public static final RegistryObject<Block> JADE_BLOCK_POLISHED = BLOCKS.register("jade_block_polished", JadeBlockPolished::new);
public static final RegistryObject<Block> MOSSY_BRICKS = BLOCKS.register("mossy_brick", MossyBricks::new);
public static final RegistryObject<Block> MOSSY_BRICK_WALL = BLOCKS.register("mossy_brick_wall",
() -> new WallBlock(Block.Properties.from(Blocks.BRICK_WALL)));
public static final RegistryObject<Block> MOSSY_BRICK_STAIR = BLOCKS.register("mossy_brick_stair", () -> new StairsBlock(() -> MOSSY_BRICKS.get().getDefaultState(), Block.Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 6.0F)));
public static final RegistryObject<Block> MOSSY_BRICK_SLAB = BLOCKS.register("mossy_brick_slab", MossyBrickSlab::new);
// Blocks Items
public static final RegistryObject<Item> JADE_CRYSTAL_BLOCK_ITEM = ITEMS.register("jade_crystal_block", () -> new BlockItemBase(JADE_CRYSTAL_BLOCK.get()));
public static final RegistryObject<Item> JADE_ORE_BLOCK_ITEM = ITEMS.register("jade_ore_block", () -> new BlockItemBase(JADE_ORE_BLOCK.get()));
public static final RegistryObject<Item> JADE_BLOCK_ITEM = ITEMS.register("jade_block", () -> new BlockItemBase(JADE_BLOCK.get()));
public static final RegistryObject<Item> JADE_BLOCK_POLISHED_ITEM = ITEMS.register("jade_block_polished", () -> new BlockItemBase(JADE_BLOCK_POLISHED.get()));
public static final RegistryObject<Item> MOSSY_BRICK_ITEM = ITEMS.register("mossy_brick", () -> new BlockItemBase(MOSSY_BRICKS.get()));
public static final RegistryObject<Item> MOSSY_BRICK_STAIR_ITEM = ITEMS.register("mossy_brick_stair", () -> new BlockItemBase(MOSSY_BRICK_STAIR.get()));
public static final RegistryObject<Item> MOSSY_BRICK_SLAB_ITEM = ITEMS.register("mossy_brick_slab", () -> new BlockItemBase(MOSSY_BRICK_SLAB.get()));
public static final RegistryObject<Item> MOSSY_BRICK_WALL_ITEM = ITEMS.register("mossy_brick_wall", () -> new BlockItemBase(MOSSY_BRICK_WALL.get()));
// Entity Types
public static final EntityType<EntityJadeArrow> JADE_ARROW_ENTITY = register("jade_arrow", EntityType.Builder.<EntityJadeArrow>create(EntityJadeArrow::new, EntityClassification.MISC).size(0.5F, 0.5F).func_233606_a_(4).func_233608_b_(20));
private static <T extends Entity> EntityType<T> register(String key, EntityType.Builder<T> builder) {
return Registry.register(Registry.ENTITY_TYPE, key, builder.build(key));
}
}
EntityJadeArrow:
package com.chuck.jademod.entities;
import com.chuck.jademod.util.RegisteryHandler;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.IPacket;
import net.minecraft.potion.*;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
public class EntityJadeArrow extends AbstractArrowEntity {
public EntityJadeArrow(World worldIn, LivingEntity shooter) {
super(RegisteryHandler.JADE_ARROW_ENTITY, shooter, worldIn);
}
public EntityJadeArrow(EntityType<EntityJadeArrow> entityJadeArrowEntityType, World world) {
super(entityJadeArrowEntityType, world);
}
protected void arrowHit(LivingEntity living) {
super.arrowHit(living);
EffectInstance effectinstance = new EffectInstance(Effects.INSTANT_DAMAGE, 1, 1);
living.addPotionEffect(effectinstance);
}
protected ItemStack getArrowStack() { return new ItemStack(RegisteryHandler.JADE_ARROW.get());}
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
}
JadeArrow:
package com.chuck.jademod.items;
import com.chuck.jademod.entities.EntityJadeArrow;
import com.chuck.jademod.util.RegisteryHandler;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.entity.projectile.SpectralArrowEntity;
import net.minecraft.item.ArrowItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public class JadeArrow extends ArrowItem {
public JadeArrow() {
super((new Item.Properties()).group(ItemGroup.COMBAT));
}
public AbstractArrowEntity createArrow(World worldIn, ItemStack stack, LivingEntity shooter) {
return new EntityJadeArrow(worldIn, shooter);
}
}
JadeArrowRenderer:
package com.chuck.jademod.render.entities;
import com.chuck.jademod.entities.EntityJadeArrow;
import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class JadeArrowRenderer extends ArrowRenderer<EntityJadeArrow> {
public static final ResourceLocation RES_JADE_ARROW = new ResourceLocation("jade:textures/entity/projectiles/arrow.png");
public JadeArrowRenderer(EntityRendererManager manager) {
super(manager);
}
public ResourceLocation getEntityTexture(EntityJadeArrow entity) {
return RES_JADE_ARROW;
}
}
Thank you for any help at all.
The arrow.png entity resource is just the same as the default arrow