Jump to content

[SOLVED][1.10.2]Issue with TESR rendering


draganz

Recommended Posts

I have a TESR that works perfectly (though needs some clean up); it will render when you place the block, but when one logs out and logs back in, the TESR will not render, though if broken and replaced, will render once again. I have tried various vanilla ways if updating the tile entity and also tried a simple network message to be sent, nothing is working. Thank you to anyone who can help.

 

NOTE: to simplify, the issue is that on logging in, an existing block does not recognize that there is a TESR class at all.

 

TESR class

 

@SideOnly(Side.CLIENT)
public class TESRSunDial extends TileEntitySpecialRenderer<TESunDial> {
private static final double RADIUS = 0.31;
private static final double BLOCK_HEIGHT = 0.813;
private static TextureAtlasSprite texture;
@Override
public void renderTileEntityAt(TESunDial tile, double x, double y, double z,
		float partialTicks, int destroyStage) {
	GlStateManager.pushMatrix();
	GlStateManager.color(0.1f, 0, 0);
	texture = Minecraft.getMinecraft().getTextureMapBlocks().getTextureExtry("sundial:blocks/sunDialBase");
	Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
        this.drawTriangle(x, y+BLOCK_HEIGHT, z, tile.getCounter(), RADIUS);
	GlStateManager.popMatrix();
}

private void drawTriangle(double x, double y, double z, float time, double radius){
	GlStateManager.pushMatrix();

	double originX = x + 0.5;
	double originZ = z + 0.5;
	float maxU = texture.getMaxU();
	float maxV = texture.getMaxV();

	double point1X = originX;
	double point1Z = originZ - radius;
	//TRICKY STUFF
	double point2X=originX,point2Z=originZ,point3X=originX,point3Z=originZ;
	if(time > 6000 && time < 18000){
		point2X = originX;
		point2Z = originZ;
		point3X = originX - xCoord(time,radius);
		point3Z = originZ - yCoord(time,radius);
	}else if(time > 18000 || time < 6000){
		point2X = originX - xCoord(time,radius);
		point2Z = originZ - yCoord(time,radius);
		point3X = originX;
		point3Z = originZ;
	}

	Tessellator tessellator = Tessellator.getInstance();
	VertexBuffer buffer = tessellator.getBuffer();

	buffer.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX);
	//POINT 1 ORIGIN
	buffer.pos(point1X, y, point1Z).tex(texture.getMinU(), maxV).endVertex();
	//POINT 2 MOVING ARM RADIUS
	buffer.pos(point2X, y, point2Z).tex(maxU, maxV).endVertex();
	//POINT 3 FINAL RADIUS
	buffer.pos(point3X, y, point3Z).tex(maxU, texture.getMinV()).endVertex();

	tessellator.draw();
	GlStateManager.popMatrix();
}
private double xCoord(float time, double radius){
	return radius*(Math.cos((Math.PI*time)/12000));
}
private double yCoord(float time, double radius){
	return radius*(Math.sin((Math.PI*time)/12000));
}

}

 

 

Tile Entity class

 

public class TESunDial extends TEBase {

private float counter;
private int subCounter;
private BlockPos pos;
private Random rand = new Random();

public TESunDial() {
	super();
	this.neutralizeCounter();
	this.neutralizePos();
	this.neutralizeSubCounter();
}

@Override
public void readFromNBT(NBTTagCompound tag) {
	super.readFromNBT(tag);
	if (tag.getBoolean(internalReference.HAS_POS)) {
		this.setPosInternal(new BlockPos(tag.getInteger(internalReference.X), tag.getInteger(internalReference.Y),
				tag.getInteger(internalReference.Z)));
	}else{ this.neutralizePos(); }
	counterSets();
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
	super.writeToNBT(tag);
	if(this.hasPos()){
		tag.setInteger(internalReference.X, this.getPosInternal().getX());
		tag.setInteger(internalReference.Y, this.getPosInternal().getY());
		tag.setInteger(internalReference.Z, this.getPosInternal().getZ());
	}
	tag.setBoolean(internalReference.HAS_POS, this.getPosInternal() != null ? true : false);
	return tag;
}

@Override
public void placeBlock(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack heldItem) {
	IBlockState key = world.getBlockState(pos.up());
	if (key != null && !(key.getBlock() instanceof BlockAir)) {
		if (isOfOr(key))
			this.setPosInternal(pos.up());
	}
	super.placeBlock(world, pos, state, placer, heldItem);
}

@Override
public void blockUpdate(IBlockState state, World world, BlockPos pos, Block block) {
	IBlockState key = world.getBlockState(pos.up());
	if(key != null){
		if(!(key.getBlock() instanceof BlockAir)){
			if (!isOfOr(key)){
				if(this.hasPos())
					this.neutralizePos();
			}else{
				this.setPosInternal(pos.up());//GO FOR THE GOLD
			}
		}else{ if(this.hasPos()){ this.neutralizePos(); } } //double check
	}else{
		if(this.hasPos()){ this.neutralizePos(); }
	}

}

@Override
public boolean activate(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
		ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
	if(player != null && heldItem != null){
		if(this.hasPos()){
			if(heldItem.getItem() == Items.CLAY_BALL){
				Block what = world.getBlockState(getPosInternal()).getBlock();
				if(this.isOfOr(what.getDefaultState())){//double check
					boolean flag = !world.isRemote;
					if(what instanceof BlockDragonEgg){
						if(flag){
							long timeSet = (((world.getWorldTime()/24000)*24000)+ConfigurationHandler.nightTime); 
							world.setWorldTime(timeSet);
							return true;
						}
					}else if(what instanceof BlockGlowstone){
						if(flag){
							long timeSet = (((world.getWorldTime()/24000)*24000)+ConfigurationHandler.dayTime); 
							world.setWorldTime(timeSet);
							return true;
						}
					}
				}
			}
		}
	}
	return super.activate(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ);
}

@Override
public void update() {
	if (rand.nextInt(10) == 1) {//DEBUG THIS VALUE
		counterSets();

	}
}

private void counterSets(){
	long time = getWorld().getWorldTime();
	setSubCounter((int)(time/24000));
	setCounter((float)(time-(getSubCounter()*24000)));
}

private void neutralizeCounter() { this.counter = 0; }

private void neutralizeSubCounter(){ this.subCounter = 0; }

private void neutralizePos() { this.pos = null; }

public float getCounter() { return counter; }

private BlockPos getPosInternal() { return pos; }

private boolean hasPos(){ return getPosInternal() != null ? true : false; }

private int getSubCounter(){ return subCounter; }

private void setCounter(float in) { this.counter = in; }

private void setPosInternal(BlockPos in) { this.pos = in; }

private void setSubCounter(int in){
	this.subCounter = in;
}

private boolean isOfOr(IBlockState state) {
	if (state.getBlock() instanceof BlockDragonEgg)
		return true;
	else if (state.getBlock() instanceof BlockGlowstone)
		return true;
	return false;
}

private final static class internalReference {
	public static final String X = stringFormatter("pos_X");
	public static final String Y = stringFormatter("pos_Y");
	public static final String Z = stringFormatter("pos_Z");
	public static final String HAS_POS = stringFormatter("hasPos");
	public static final String COUNTER = stringFormatter("counter");
	public static final String SUB_COUNTER = stringFormatter("subCounter");

	private static String stringFormatter(String in) {
		return "TESunDial:" + in;
	}
}

}

 

 

TEBase

 

public abstract class TEBase extends TileEntity implements ITickable{
public TEBase(){
	super();
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet){
	readFromNBT(packet.getNbtCompound());
}

@Override
public NBTTagCompound getUpdateTag(){
	return writeToNBT(new NBTTagCompound());
}

@Override
public SPacketUpdateTileEntity getUpdatePacket(){
	return new SPacketUpdateTileEntity(getPos(), 0, getUpdateTag());
}

public void placeBlock(World world, BlockPos pos, IBlockState state, EntityLivingBase placer,
		ItemStack heldItem){
	this.validate();
}//CALLED: ModBlocks.BlockTEBase

public void blockUpdate(IBlockState state, World worldIn, BlockPos pos, Block block){ }//CALLED: ModBlocks.BlockTEBase

public boolean activate(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ){
	return false;
}//CALLED: ModBlocks.BlockTEBase
}

 

 

Common Proxy

 

public abstract class CommonProxy implements IProxy {

public void renders() {
}

@Override
public void initMaps() {
	for (ModItems out : ModItems.values())
		GameRegistry.register(out.getItemClass().setUnlocalizedName(out.getName()).setRegistryName(out.getName()));
	for(ModBlocks out : ModBlocks.values()){
		if(registerBlock(out)){
			GameRegistry.registerTileEntity(out.getTEClass(), constructTEName(out.getName()));
			if(out.getTESRClass() != null)
				ClientRegistry.bindTileEntitySpecialRenderer(out.getTEClass(), out.getTESRClass());
		}
	}
}
protected boolean registerBlock(ModBlocks in){
	GameRegistry.register(in.getBlockClass().setUnlocalizedName(in.getName()).setRegistryName(in.getName()));
	GameRegistry.register(in.getItemBlock(), in.getBlockClass().getRegistryName());
	return in.getTEClass() != null;
}
protected String constructTEName(String name){
	return Reference.MOD_ID_Prime+"TileEntity"+name;
}
}

 

 

Client Proxy

 

public class ClientProxy extends CommonProxy {
public void renders() {
	for(ModItems out : ModItems.values())
			((ItemGeneric)out.getItemClass()).initModel();

	for(ModBlocks out : ModBlocks.values())
			out.getBlockClass().initModel();
}
}

 

 

Main class

 

@Mod(modid = Reference.MOD_ID, name = Reference.MOD_NAME, version = Reference.VERSION, guiFactory = Reference.GUI_FACTORY_CLASS)
public class SunDial {
@Mod.Instance(Reference.MOD_ID)
public static SunDial instance;

public static final CreativeTabs SUNDIAL_TAB = new CreativeTabs(Reference.MOD_ID) {
	@Override
	public Item getTabIconItem() {
		return Items.APPLE;
	}
};

@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS)
public static IProxy proxy;

@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
	ConfigurationHandler.init(event.getSuggestedConfigurationFile());
	MinecraftForge.EVENT_BUS.register(new ConfigurationHandler());
	proxy.initMaps();
	proxy.renders();
}

}

 

Link to comment
Share on other sites

Solved the Issue, was a issue in loading NBT data, somehow i did not notice and error warning that said how it could not load NBT data due to the tile entity trying to get the world time before it could access the world time, causing the needed NBT data to not be read.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • It does but I'm struggling to see how to make it work in my recipe? (Its structure is the same as OP's, with a serializer subclass)
    • That looks pretty cool, nice!   Sure, so looking at that JSON file I posted, I pretty much made a record class for each "custom" data type in that JSON. The Input is a good example of why ``` "inputs": [ { "ingredient": { "item": "relativedimensions:aberrant_shard" }, "count": 8 } ], ``` So here's the inputs, it's an array, which we can use the Codec builder's builder.listOf to define an array. Each Item is of some arbitrary object with keys "ingredient" (which we know is an Ingredient) and a "count" which is an int. You don't have to have an intermediate class to map this to necessarily but I found that it's just easier to see the data that way, hence the 'ParticleReboundIngredient' represents one of these inputs.   Let me know if that makes sense or not. 
    • Pretty much, although all the recipes im planning to make on it are shapeless. The idea is that the chamber uses energy to "fuse" the items in each of the center slots together, in this case an ingot. The two slots at the sides are fuel. (A special kind of wood in this case). Here is an image of the interface just for reference (The center slot is the output)   As for the code- Can you elaborate a little bit on it? Seeing three different record classes has confused me a lot. (Elaborate as in why make them in three different records. I understand the code itself more or less)
    • Hello im trying to make a mod and the past few days GSON has almost killed me, when i export the mod and then launch it through minecraft launcher i get java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement; i have literally tried everything here is my build config   dependencies { minecraft("com.mojang:minecraft:1.8.9") mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") compileOnly("cc.polyfrost:oneconfig-1.8.9-forge:0.2.2-alpha+") shadowImpl("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") { isTransitive = false exclude(module = "gson") } shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") { isTransitive = false exclude(module = "gson") } annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT") shadowImpl("org.javassist:javassist:3.15.0-GA") { isTransitive = false exclude(module = "gson") } shadowImpl("com.neovisionaries:nv-i18n:1.28") { isTransitive = false exclude(module = "gson") } shadowImpl("org.apache.commons:commons-lang3:3.4") { isTransitive = false exclude(module = "gson") } shadowImpl("org.apache.httpcomponents:httpcore:4.4.5") { isTransitive = false exclude(module = "gson") } compileOnly("com.google.code.gson:gson:2.8.6") { isTransitive = false } configurations.all { resolutionStrategy { force("com.google.code.gson:gson:2.8.6") } } shadowImpl(fileTree( mapOf( "dir" to "libs", "include" to listOf("*.jar"), "exclude" to listOf( "asm", "asm-commons", "asm-tree", "gson", "unspecified", "nv-i18n" ) ) )) }  
    • @chxr Looks like you're making some sort of a crafting table / furnace hybrid? Are the inputs needing arranging like a shaped recipe, or is it shapeless? I'll assume it's shapeless since that just adds a lot more complexity. In that case I'd probably do something like this { "type": "relativedimensions:particle_rebound", "inputs": [ { "ingredient": { "item": "relativedimensions:aberrant_shard" }, "count": 8 } ], "fuel": { "tag": "relativedimensions:block/aberrant_fuel" }, "output": { "Count": 1, "id": "relativedimensions:aberrant_ingot" } } inputs: A list of ingredients and how many are needed. The count among each input adds up to 8. Since there's only 1 ingredient, the count is set to 8. fuel: Same thing as before but remove the list and just make it an object with a tag. output: Kept the same.   In this case the Codec I would make is public record ParticleReboundIngredient(Ingredient ingredient, int count) { public static final Codec<ParticleReboundIngredient> CODEC = RecordCodecBuilder.create( builder -> builder.group( Ingredient.CODEC.fieldOf("ingredient").forGetter((i) -> i.ingredient), Codec.INT.fieldOf("count").forGetter(i -> i.count) ).apply(builder, ParticleReboundIngredient::new) ); } public record ParticleReboundFuel(String tag) { public static final Codec<ParticleReboundFuel> CODEC = RecordCodecBuilder.create( builder -> builder.group(Codec.STRING.fieldOf("tag").forGetter(f -> f.tag)).apply(builder, ParticleReboundFuel::new) ); public boolean isFuel(ItemStack stack) { // TODO: Check if fuel item matches the tag } } public record ParticleReboundRecipe(List<ParticleReboundIngredient> inputs, ParticleReboundFuel fuel, ItemStack output) { public static final Codec<ParticleReboundRecipe> CODEC = RecordCodecBuilder.create( builder -> builder.group( ParticleReboundIngredient.CODEC.listOf().fieldOf("inputs").forGetter(r -> r.inputs), ParticleReboundFuel.CODEC.fieldOf("fuel").forGetter(r -> r.fuel), ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output) ).apply(builder, ParticleReboundRecipe::new) ); }   There might be a more proper Codec for the fuel and the tag that's built into minecraft / forge, but I didn't look
  • Topics

×
×
  • Create New...

Important Information

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