Simple Modding Help Thread (Ask a Simple Question Get a Simple Answer Forge & Java Edition)

Bl@ckHole

New Member
Jul 29, 2019
22
0
0
So, I'm trying to make a custom explosive block, and the problem is that the primed explosive entity is invisible. It is there, and it explodes, but it's invisible. Here are the relevant parts of the code :

The class for the entity
Code:
package com.ceselegend.rozmod.entity;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;

public class RozNukePrimed extends Entity {

  public int fuse;
  private EntityLivingBase tntPlacedBy;

  public RozNukePrimed(World world) {
  super(world);
  this.preventEntitySpawning = true;
  this.setSize(0.98F, 0.98F);
  this.yOffset = this.height / 2.0F;
  }

  public RozNukePrimed(World world, double posX, double posY, double posZ, EntityLivingBase entity) {
  this(world);
  this.setPosition(posX, posY, posZ);
  float f = (float)(Math.random() * Math.PI * 2.0D);
  this.motionX = (double)(-((float)Math.sin((double)f)) * 0.02F);
  this.motionY = 0.20000000298023224D;
  this.motionZ = (double)(-((float)Math.cos((double)f)) * 0.02F);
  this.fuse = 80;
  this.prevPosX = posX;
  this.prevPosY = posY;
  this.prevPosZ = posZ;
  this.tntPlacedBy = entity;
  }

  protected void entityInit() {}

  /**
  * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
  * prevent them from trampling crops
  */
  protected boolean canTriggerWalking()
  {
  return false;
  }

  /**
  * Returns true if other Entities should be prevented from moving through this Entity.
  */
  public boolean canBeCollidedWith()
  {
  return !this.isDead;
  }

  /**
  * Called to update the entity's position/logic.
  */
  public void onUpdate()
  {
  this.prevPosX = this.posX;
  this.prevPosY = this.posY;
  this.prevPosZ = this.posZ;
  this.motionY -= 0.03999999910593033D;
  this.moveEntity(this.motionX, this.motionY, this.motionZ);
  this.motionX *= 0.9800000190734863D;
  this.motionY *= 0.9800000190734863D;
  this.motionZ *= 0.9800000190734863D;

  if (this.onGround)
  {
  this.motionX *= 0.699999988079071D;
  this.motionZ *= 0.699999988079071D;
  this.motionY *= -0.5D;
  }

  if (this.fuse-- <= 0)
  {
  this.setDead();

  if (!this.worldObj.isRemote)
  {
  this.explode();
  }
  }
  else
  {
  this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
  }
  }

  private void explode()
  {
  float f = 32.0F;
  this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, f, true);
  }

  /**
  * (abstract) Protected helper method to write subclass entity data to NBT.
  */
  protected void writeEntityToNBT(NBTTagCompound tagNBT)
  {
  tagNBT.setByte("Fuse", (byte)this.fuse);
  }

  /**
  * (abstract) Protected helper method to read subclass entity data from NBT.
  */
  protected void readEntityFromNBT(NBTTagCompound tagNBT)
  {
  this.fuse = tagNBT.getByte("Fuse");
  }

  @SideOnly(Side.CLIENT)
  public float getShadowSize()
  {
  return 0.0F;
  }

  /**
  * returns null or the entityliving it was placed or ignited by
  */
  public EntityLivingBase getTntPlacedBy()
  {
  return this.tntPlacedBy;
  }
}

Then renderer class associated with it :
Code:
package com.ceselegend.rozmod.render;


import com.ceselegend.rozmod.entity.RozNukePrimed;
import com.ceselegend.rozmod.init.ModBlocks;
import com.ceselegend.rozmod.utility.LogHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;

@SideOnly(Side.CLIENT)
public class RenderRozNukePrimed extends Render {
  private RenderBlocks blockRenderer = new RenderBlocks();
  private static final ResourceLocation entityTexture = new ResourceLocation("RozNuke_side.png");

  public RenderRozNukePrimed()
  {
  this.shadowSize = 0.5F;
  }

  /**
  * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
  * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
  * (Render<T extends Entity) and this method has signature public void func_76986_a(T entity, double d, double d1,
  * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
  */
  public void doRender(RozNukePrimed p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
  {
  LogHelper.info("Render called !");
  GL11.glPushMatrix();
  GL11.glTranslatef((float)p_76986_2_, (float)p_76986_4_, (float)p_76986_6_);
  float f2;

  if ((float)p_76986_1_.fuse - p_76986_9_ + 1.0F < 10.0F)
  {
  f2 = 1.0F - ((float)p_76986_1_.fuse - p_76986_9_ + 1.0F) / 10.0F;

  if (f2 < 0.0F)
  {
  f2 = 0.0F;
  }

  if (f2 > 1.0F)
  {
  f2 = 1.0F;
  }

  f2 *= f2;
  f2 *= f2;
  float f3 = 1.0F + f2 * 0.3F;
  GL11.glScalef(f3, f3, f3);
  }

  f2 = (1.0F - ((float)p_76986_1_.fuse - p_76986_9_ + 1.0F) / 100.0F) * 0.8F;
  this.bindEntityTexture(p_76986_1_);
  this.blockRenderer.renderBlockAsItem(ModBlocks.rozNuke, 0, p_76986_1_.getBrightness(p_76986_9_));

  if (p_76986_1_.fuse / 5 % 2 == 0)
  {
  GL11.glDisable(GL11.GL_TEXTURE_2D);
  GL11.glDisable(GL11.GL_LIGHTING);
  GL11.glEnable(GL11.GL_BLEND);
  GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA);
  GL11.glColor4f(1.0F, 1.0F, 1.0F, f2);
  this.blockRenderer.renderBlockAsItem(ModBlocks.rozNuke, 0, 1.0F);
  GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
  GL11.glDisable(GL11.GL_BLEND);
  GL11.glEnable(GL11.GL_LIGHTING);
  GL11.glEnable(GL11.GL_TEXTURE_2D);
  }

  GL11.glPopMatrix();
  }

  /**
  * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
  */
  protected ResourceLocation getEntityTexture(RozNukePrimed p_110775_1_)
  {
  return entityTexture;
  }

  /**
  * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
  */
  protected ResourceLocation getEntityTexture(Entity p_110775_1_)
  {
  return this.getEntityTexture((RozNukePrimed)p_110775_1_);
  }

  /**
  * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
  * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
  * (Render<T extends Entity) and this method has signature public void func_76986_a(T entity, double d, double d1,
  * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
  */
  public void doRender(Entity p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
  {
  this.doRender((RozNukePrimed)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_);
  }
}

The registering of the renderer in the ClientProxy :
Code:
RenderingRegistry.registerEntityRenderingHandler(RozNukePrimed.class, new RenderRozNukePrimed());

The entity registering in the main file :
Code:
 EntityRegistry.registerGlobalEntityID(RozNukePrimed.class, "rozNukePrimed", EntityRegistry.findGlobalUniqueEntityId());
  EntityRegistry.registerModEntity(RozNukePrimed.class,"rozNukePrimed",1,this,128,1,false);

I've tried to add some debug lines, and it seems that the doRender() method of the renderer is never called, in fact the constructor of the renderer class never seems to be called; but I have no idea why. If you want to check the code in more details, here is the link to the code's Github
 

ljfa

New Member
Jul 29, 2019
2,761
-46
0
So, I'm trying to make a custom explosive block, and the problem is that the primed explosive entity is invisible. It is there, and it explodes, but it's invisible. Here are the relevant parts of the code :
Maybe try registering the renderer in init() rather than preInit()
 

ljfa

New Member
Jul 29, 2019
2,761
-46
0
Yes, do all registering in the init. Doing any registering in the preinit or postinit might break (my) universal tweaks.
I wonder if someone made a list of what belongs where, or if it's just unspoken rules
 

ljfa

New Member
Jul 29, 2019
2,761
-46
0
The unspoken rules are:

  • *Configs in the preinit
    *Adding the content in the init
    *Adding compatibility in the postinit
Well I guess you can't 100% count on what is being initialized where. Recipes can be added in preInit (e.g. Botania), init or postInit.
 

VapourDrive

New Member
Jul 29, 2019
536
-8
1
Yeah factorization registers recipes late as far as I can tell, they get left in if you try to remove all recipes with a specific itemstack output :/