Hello,
I am having great difficulties trying to render a custom, 2D entity - pretty much exactly like a snowball.
Seeing as I want it to render and behave like a snowball, I figured that I would instantiate the RenderSnowball class to render my own entity, as the class accepts subclasses of Entity.
However, when I spawn it in by right clicking with an item, the game crashes with a NullPointerException. Now, looking through the crash report in the console, one line immediately stands out:
-- Head --
Thread: Client thread
Stacktrace:
at net.minecraft.client.renderer.entity.RenderSnowball.doRender(RenderSnowball.java:46)
As line 46 involves rendering an ItemStack, I assumed that I passed in an Item incorrectly into the constructor for the RenderSnowball. IntelliJ warns me that ModItems::PING_PONG_BALL might be null, but I thought that this was to be expected as a result of using @ObjectHolder annotations. So, do I need to give the constructor my ItemPingPongBall from the GameRegistry instead? Or is there something else going on here that I am completely overlooking?
All relevant classes can be found below, and a crash log is attached.
ClientProxy:
public class ClientProxy{
public void preInit(){
ModRenderers.register();
}
public void init(){
}
public void postInit(){
}
}
ModRenderers:
public final class ModRenderers{
private static RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
public static void register(){
RenderingRegistry.registerEntityRenderingHandler(EntityPingPongBall.class,
renderManager -> new RenderSnowball<>(renderManager, ModItems.PING_PONG_BALL, renderItem));
}
}
ModItems:
@ObjectHolder(RaddariMod.MOD_ID)
public final class ModItems{
@ObjectHolder("pingpong_ball")
public static final ItemPingPongBall PING_PONG_BALL = Null();
@Mod.EventBusSubscriber(modid = RaddariMod.MOD_ID)
public static class RegistrationHandler{
public static final Set<Item> ITEMS = new HashSet<>();
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event){
final Item[] items = {
new ItemPingPongBall(),
};
final IForgeRegistry<Item> registry = event.getRegistry();
for(Item item : items){
registry.register(item);
ITEMS.add(item);
}
}
}
}
ModEntities:
@ObjectHolder(RaddariMod.MOD_ID)
public final class ModEntities{
@ObjectHolder("pingpong_ball")
public static final EntityEntry PING_PONG_BALL = Null();
@Mod.EventBusSubscriber(modid = RaddariMod.MOD_ID)
public static class RegistrationHandler{
@SubscribeEvent
public static void registerEntities(RegistryEvent.Register<EntityEntry> event){
final EntityEntry[] entities = {
createBuilder("pingpong_ball")
.entity(EntityPingPongBall.class)
.tracker(32, 20, true)
.build(),
};
final IForgeRegistry<EntityEntry> registry = event.getRegistry();
registry.registerAll(entities);
}
private static int entityID = 0;
private static <E extends Entity> EntityEntryBuilder<E> createBuilder(String name){
EntityEntryBuilder<E> builder = EntityEntryBuilder.create();
ResourceLocation registryName = new ResourceLocation(RaddariMod.MOD_ID, name);
return builder.id(registryName, entityID++).name(registryName.toString());
}
}
}
And finally, ItemRaddari, which my ItemPingPongBall class extends:
public class ItemRaddari extends Item{
public ItemRaddari(String registryName){
if(StringHelper.hasContent(registryName)){
ItemRaddari.setItemName(this, registryName);
}else{
throw new RuntimeException("Item " + this.getClass().getName() + " has an invalid name!");
}
}
private static void setItemName(Item item, String registryName){
item.setRegistryName(RaddariMod.MOD_ID, registryName);
item.setUnlocalizedName(item.getRegistryName().toString());
//System.out.println(String.format("Item name assigned: [%s] [%s} [%s]", item.getClass().getName(), item.getRegistryName(), item.getUnlocalizedName()));
}
}
Thank you,
Raddari
crash-2018-02-04_16.47.57-client.txt