Jump to content

Custom arrow rendering entity not shown


Xanatos

Recommended Posts

Hey there,

 

I know there are a lot of threads for custom entity rendering with different solutions like the following: https://forums.minecraftforge.net/topic/84158-1152-solved-custom-arrow-entity-not-rendering/

I tried a lot of things and I cannot get the arrow/bullet into a state where it is rendererd ...

 

 

Mod entry point

package com.xanatos.flintlock;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

@Mod(FlintlockMod.MODID)
public class FlintlockMod {

    // Directly reference a log4j logger.
    private static final Logger LOGGER = LogManager.getLogger();
    public static final String MODID = "flintlock";
    
	public FlintlockMod() 
	{
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        
        MinecraftForge.EVENT_BUS.register(this);
        RegistryHandler.init();
	}

    private void setup(final FMLCommonSetupEvent event)
    {
        LOGGER.info("HELLO FROM FlintlockRegister");
    }
}

 

Item/entity registration

package com.xanatos.flintlock;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.xanatos.flintlock.ammo.Bullet;
import com.xanatos.flintlock.entities.BulletEntity;
import com.xanatos.flintlock.weapons.pistol.*;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;

public class RegistryHandler {    
	private static final Logger LOGGER = LogManager.getLogger();
    public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, FlintlockMod.MODID);
    public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITIES, FlintlockMod.MODID);
    
    public static void init() {
        // attach DeferredRegister to the event bus
        ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
        ENTITY_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus());
        

        LOGGER.debug("Bullet resource!");
        LOGGER.debug(new ResourceLocation(FlintlockMod.MODID, "textures/items/flintlock_default_ammo.png").toString());
    }
    
    public static final RegistryObject<Item> FlintlockPistol = ITEMS.register("flintlock_pistol", () ->
			new FlintlockPistol(
					new Item.Properties().group(ItemGroup.COMBAT).maxDamage(2)
					)
    		);
    
    public static final RegistryObject<Item> FLintlockDefaultAmmo = ITEMS.register("flintlock_default_ammo", () ->
			new Bullet(
					new Item.Properties().group(ItemGroup.COMBAT).maxStackSize(64)
					)
    		);
    
    public static final RegistryObject<Item> FlintlockRawBullet = ITEMS.register("flintlock_raw_bullet", () ->
			new Item(
					new Item.Properties().group(ItemGroup.MISC).maxStackSize(64)
					)
    		);
    
    public static final RegistryObject<Item> FlintlockRefinedBullet = ITEMS.register("flintlock_refined_bullet", () ->
			new Item(
					new Item.Properties().group(ItemGroup.MISC).maxStackSize(64)
					)
    		);
    
    public static final RegistryObject<EntityType<BulletEntity>> BULLET_ENTITY =
            ENTITY_TYPES.register("flintlock_bullet_entity",
            		() -> EntityType.Builder.<BulletEntity>create(BulletEntity::new, EntityClassification.CREATURE)
                    .size(0.5f, 0.5f)
                    .build("flintlock_bullet_entity")); //new ResourceLocation(FlintlockMod.MODID, "textures/items/flintlock_default_ammo.png").toString())
}

 

Renderer registration

package com.xanatos.flintlock;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.xanatos.flintlock.entities.BulletEntity;
import com.xanatos.flintlock.renderer.BulletRenderer;

import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;

@EventBusSubscriber(value = Dist.CLIENT, modid = FlintlockMod.MODID, bus = EventBusSubscriber.Bus.MOD)
public class ModelHandler {
	

    private static final Logger LOGGER = LogManager.getLogger();
	@SubscribeEvent
	public static void registerModels(ModelRegistryEvent event) {
		LOGGER.debug("registerModels!");
		RenderingRegistry.registerEntityRenderingHandler(RegistryHandler.BULLET_ENTITY.get(), BulletRenderer::new);
	}
}

 

Renderer

package com.xanatos.flintlock.renderer;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.xanatos.flintlock.FlintlockMod;
import com.xanatos.flintlock.entities.BulletEntity;

import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.util.ResourceLocation;

public class BulletRenderer<T extends BulletEntity> extends ArrowRenderer<T> {

	public static final ResourceLocation BULLET_RESOURCE_LOCATION = new ResourceLocation(FlintlockMod.MODID, "textures/items/flintlock_default_ammo.png");
    private static final Logger LOGGER = LogManager.getLogger();
    
	public BulletRenderer(EntityRendererManager renderManagerIn) {
		super(renderManagerIn);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void render(T entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn,
			IRenderTypeBuffer bufferIn, int packedLightIn) {
		// TODO Auto-generated method stub
		super.render(entityIn, entityYaw, partialTicks, matrixStackIn, bufferIn, packedLightIn);

		LOGGER.debug("Render!!!!");
	}

	@Override
	public ResourceLocation getEntityTexture(T entity) {
		// TODO Auto-generated method stub
		LOGGER.debug("get entity texture!");
		LOGGER.debug(BULLET_RESOURCE_LOCATION);
		return BULLET_RESOURCE_LOCATION;
	}

}

BulletEntity

package com.xanatos.flintlock.entities;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.xanatos.flintlock.RegistryHandler;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.IPacket;
import net.minecraft.network.play.server.SSpawnObjectPacket;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

public class BulletEntity extends AbstractArrowEntity {
	protected static final Logger LOGGER = LogManager.getLogger();
	public BulletEntity(EntityType<? extends BulletEntity> type, World worldIn) {
		super(type, worldIn);
		pickupStatus = AbstractArrowEntity.PickupStatus.DISALLOWED;
	}
	
	public BulletEntity(World worldIn, LivingEntity shooter) {
		super(RegistryHandler.BULLET_ENTITY.get(), shooter, worldIn);
		pickupStatus = AbstractArrowEntity.PickupStatus.DISALLOWED;
	}

	@Override
	public IPacket<?> createSpawnPacket() {
	      Entity entity = this.func_234616_v_();
	      NetworkHooks.getEntitySpawningPacket(entity);
	      return new SSpawnObjectPacket(this, entity == null ? 0 : entity.getEntityId());
	}

	@Override
	public ItemStack getArrowStack() {
		return new ItemStack(RegistryHandler.FLintlockDefaultAmmo.get());
	}
	
	@Override
	protected void arrowHit(LivingEntity living) {
		// TODO Auto-generated method stub
		super.arrowHit(living);
		LOGGER.debug("hit");
		LOGGER.debug(this);
	}
	
	@Override
	protected void onEntityHit(EntityRayTraceResult p_213868_1_) {
		super.onEntityHit(p_213868_1_);
		LOGGER.debug("hit entity!");
		//this.entityDropItem(RegistryHandler.FlintlockRawBullet.get());
	}
	
	@Override
	protected void onImpact(RayTraceResult result) {
		super.onImpact(result);
		result.getHitVec();
		dropBullet(result.getHitVec());
	}
	
	protected boolean dropBullet(Vector3d hitPosition)
	{
		return dropBullet(hitPosition, RegistryHandler.FlintlockRawBullet.get());
	}
	
	
	protected boolean dropBullet(Vector3d hitPosition, Item itemIn)
	{
		ItemStack item = new ItemStack(RegistryHandler.FlintlockRawBullet.get());
		ItemEntity itementity = new ItemEntity(this.world, hitPosition.x, hitPosition.y, hitPosition.z, item);
		itementity.setDefaultPickupDelay();
		return this.world.addEntity(itementity);
	}
}

 

WeaponCode

package com.xanatos.flintlock.weapons;

import java.util.Random;
import java.util.function.Predicate;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.xanatos.flintlock.RegistryHandler;
import com.xanatos.flintlock.ammo.Bullet;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.item.ArrowItem;
import net.minecraft.item.BowItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.ShootableItem;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;

public class FlintlockWeapon extends ShootableItem {
	   public static final Predicate<ItemStack> BULLETS = (stack) -> {
		      return stack.getItem() instanceof Bullet;
		   };
	protected static final Logger LOGGER = LogManager.getLogger();
	
	private int maxInAccuracy;
	
	public FlintlockWeapon(Properties properties) {
		super(properties);
		setInaccuracy(0);
	}
	
	protected void setInaccuracy(int inAccuracy)
	{
		maxInAccuracy = inAccuracy;
	}

	
	@Override
	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {

		ItemStack weapon = playerIn.getHeldItem(handIn);
		if (playerIn.isInWater()) {
			return ActionResult.resultFail(weapon);
		}		
		ItemStack ammo = playerIn.findAmmo(weapon);
		if (!playerIn.isCreative() && !canFire(playerIn, ammo)) {
			return ActionResult.resultFail(weapon);
		}
		
		onFire(weapon, ammo, worldIn, playerIn);
		return ActionResult.resultSuccess(weapon);
	}
	
	@Override
	public void onPlayerStoppedUsing(ItemStack stack, World worldIn, LivingEntity entityLiving, int timeLeft) {
		LOGGER.debug("Stopped action!");
	}
	
	private boolean canFire(PlayerEntity player, ItemStack ammo) {
		return ammo.isEmpty() || !(ammo.getItem() instanceof Bullet);
	}
	
	protected void setBulletVelocity(float bulletVelocity)
	{
		//this.bulletVelocity = bulletVelocity;
	}
	
	protected float getBulletVelocity()
	{
		//return bulletVelocity;
		return 0f;
	}
	
	protected void onFire(ItemStack weapon, ItemStack bulletItem, World worldIn, PlayerEntity player)
	{
		if (!player.isCreative() && !canFire(player, bulletItem)) {
			return;
		}
		
		if (!worldIn.isRemote) {
			weapon.damageItem(1, player, (p_220009_1_) -> p_220009_1_.sendBreakAnimation(player.getActiveHand()));
			
			Vector3d direction = player.getLookVec();
			LOGGER.debug(bulletItem);
			Bullet bullet = (Bullet)(bulletItem.getItem() instanceof Bullet ? bulletItem.getItem() : RegistryHandler.FLintlockDefaultAmmo.get());
			LOGGER.debug(bullet);
			direction = new Vector3d(direction.x * 10, direction.y * 10, direction.z * 10);
			if (maxInAccuracy > 0) {
				Random r = new Random();
				direction = direction.add(r.nextInt(maxInAccuracy), r.nextInt(maxInAccuracy), r.nextInt(maxInAccuracy));
			}

			AbstractArrowEntity bulletEntity = bullet.createArrow(worldIn, bulletItem, player);
			bulletEntity.func_234612_a_(player, player.rotationPitch, player.rotationYaw, 0.0F, 10f * 3.0F, 1.0F);
			
			LOGGER.debug(bulletEntity);
			LOGGER.debug("Spawn entity");
			boolean successful = worldIn.addEntity(bulletEntity);
			LOGGER.debug("Spawn was " + successful);
			if (!player.isCreative()) {
				bulletItem.shrink(1);
			}
		}
	}

	@Override
	public Predicate<ItemStack> getInventoryAmmoPredicate() {
		return BULLETS;
	}

	@Override
	public int func_230305_d_() {
		return 0;
	}
}

The entity is getting spawend since the raw bullet item is getting dropped and it is doing some damage ... The bullet entity itself is not visible while it is flying to the target and I do not know why. I think there is somthing wrong with either the ResourceLocation or how I do bind the renderer to the item.

 

Edit: pasted whole weapon code instead of just the spawn part.

 

I did start yesterday with modding so feel free to correct things which could be done better :)

 

Thank you in advance for helping

 

 

2021-02-17 15_17_56-Microsoft Store.png

Edited by Xanatos
Link to comment
Share on other sites

10 minutes ago, diesieben07 said:

This is the wrong place to do this. Read the documentation for registerEntityRenderingHandler.

 

This is completely broken.

  1. func_234616_v_ returns the shooter. Why would you return a spawning packet for the shooter here? That makes zero sense.
  2. You call getEntitySpawningPacket, but completely ignore it. You must use it as your spawning packet, SSpawnObjectPacket and other vanilla spawning packets do not work for modded entities.

I think I fixed the second issue like so

 

	@Override
	public IPacket<?> createSpawnPacket() {
	      return NetworkHooks.getEntitySpawningPacket(this);
	}

 

Now I do get an black arrow shaped thing which is already visible, this is a good start!

The first point I cannot find a documentation I do understand. I did read multiple times through the following part https://mcforge.readthedocs.io/en/latest/concepts/registries/

 

but still don't get it :(

2021-02-17 15_51_28-Minecraft_ 1.16.5 - Singleplayer.png

Edited by Xanatos
Upload image of bullet
Link to comment
Share on other sites

39 minutes ago, diesieben07 said:

You should try making screenshots during daytime, so we can actually see something.

Sure, sorry since I do inherit from the ArrowRenderer I do get the arrow object form without any texture. This is something.

 

Is there any documentation for the render method and how the vertex are used in minecraft?

 

 

Edited by Xanatos
Link to comment
Share on other sites

I think you solved my issue by explaining the "createSpawnPackage" method. The bullets are rendered correctly. I still need to fix the registry you mentioned but it still seems to work.

 

The registration should be part of the "pre-init" hook which is the "setup" method in the examplemod delivered with forge, right?

 

Can I mark this thread as solved and give you some credits for helping me?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.