Jump to content

TileEntitySpecialRenderer problems (texture flickers)!


AskHow1248

Recommended Posts

I have a block with a custom amount of "power" in it, and I want the block to get brighter as there is more power.  I have three textures I want to use for different power ranges, but when the block gets into a new power range, it dosen't update.  If I place a block next to it, or force it to update, it works, but it won't work on it's own.  I think it might have something to do with textures being client-side and tile entities being server-side, but I dont know how to fix it.  Thanks in advance for any help.

 

Block:

 

 

package Technomage3.both.Blocks;

import java.util.Random;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import am2.AMCore;
import am2.blocks.BlocksCommonProxy;
import am2.particles.AMParticle;
import am2.particles.ParticleFloatUpward;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import Technomage3.Core.Blocks.TN3Block;
import Technomage3.Core.Blocks.TN3BlockContainer;
import Technomage3.Core.Utils.TN3Utils;
import Technomage3.both.Blocks.tileentities.TileEntityMagicRune;
import Technomage3.both.Power.IUsePower;

public class BlockMagicRune extends TN3BlockContainer {

private Icon[] icons = new Icon[3];

public BlockMagicRune(String realName, String unlocalizedName, CreativeTabs tab) {
	super(realName, unlocalizedName, tab);
	this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.01F, 1.0F);
	this.setLightOpacity(0);
	this.setTickRandomly(true);
}

public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
	return AxisAlignedBB.getAABBPool().getAABB((double)par2 + super.minX, (double)par3 + super.minY, (double)par4 + super.minZ, (double)par2 + super.maxX, (double)par3 + super.maxY, (double)par4 + super.maxZ);
}

public void setBlockBoundsForItemRender()
{
	this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.01F, 1.0F);
}


public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int meta, float hitX, float hitY, float hitZ)
{

	TileEntityMagicRune tile = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	if(!world.isRemote){
		player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(
				"Power Level: " + tile.getPowerLevel() + 
				", Power: " + tile.getPower()
				));
	}

	return true;
}

@Override
public TileEntity createNewTileEntity(World world) {
	return new TileEntityMagicRune();
}

public void randomDisplayTick(World world, int x, int y, int z, Random rand)
{
	if(world.isRemote && this.getPowerLevel(world, x, y, z) >= 50){

	} else if(world.isRemote && this.getPowerLevel(world, x, y, z) >= 0){


	} else{



	}
}

public int getPowerLevel(IBlockAccess world, int x, int y, int z) {

	TileEntityMagicRune tile = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	return tile.getPowerLevel();
}


public Icon getBlockTexture(IBlockAccess world, int x, int y, int z, int par5)
{

	if(this.getPowerLevel(world, x, y, z) > 30){

		return icons[2];

	} else if(this.getPowerLevel(world, x, y, z) > 0){

		return icons[1];

	} else{

		return icons[0];

	}

}

public void registerIcons(IconRegister register)
{

	icons[2] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneHigh");

	icons[1] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneMid");

	icons[0] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneLow");

}

public Icon getIcon(int par1, int par2)
{
	return icons[1];
}

public int tickRate(World par1World)
{
	return 1;
}

public void onBlockAdded(World world, int x, int y, int z) {

	TileEntityMagicRune rune = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	rune.onCreated();

}

public boolean renderAsNormalBlock()
{
	return false;
}

public boolean isOpaqueCube()
{
	return false;
}

public static boolean isNormalCube(int par0)
    {
        return false;
    }
public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    {
        return false;
    }

public boolean getTickRandomly()
    {
        return true;
    }

public void updateTick(World world, int x, int y, int z, Random rand)
{

	world.scheduleBlockUpdate(x, y, z, super.blockID, this.tickRate(world));

}

}

 

 

 

TileEntity:

 

 

package Technomage3.both.Blocks.tileentities;

import java.util.ArrayList;
import java.util.Stack;

import Technomage3.both.Blocks.TMBlocks;
import Technomage3.both.Power.IRecivePower;
import Technomage3.both.Power.IUsePower;
import Technomage3.both.Power.PowerHelper;
import Technomage3.both.Power.PowerPacket;
import Technomage3.both.Power.TileEntityMagicConduit;
import Technomage3.both.Power.TileEntityMagicMachine;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;

public class TileEntityMagicRune extends TileEntity {

private int power = 0;

public static final int ratio = 50; 

public void updateEntity() {

	worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, TMBlocks.magicRune.blockID, 1);

}

public static class MagicRunePowerHandeler implements IRecivePower {

	private World world;

	private ArrayList<TileEntityMagicRune> runes;

	private PowerPacket power;

	public MagicRunePowerHandeler(TileEntityMagicRune tile) {

		world = tile.worldObj;

		runes = findAll(tile);

		power = new PowerPacket();

		setPower(new PowerPacket(getMaxPower(runes)));

	}

	private int getMaxPower(ArrayList<TileEntityMagicRune> runes2) {

		int max = 0;

		for(TileEntityMagicRune r : runes2)
			if(r.getPower() > max)
				max = r.getPower();

		return max;
	}

	public static ArrayList<TileEntityMagicRune> findAll(TileEntityMagicRune rune){

		ArrayList<TileEntityMagicRune> runes = new ArrayList<TileEntityMagicRune>();

		Stack<TileEntityMagicRune> qeue = new Stack<TileEntityMagicRune>();

		qeue.add(rune);

		while(!qeue.isEmpty()){

			TileEntityMagicRune r = qeue.pop();

			if(!runes.contains(r))
				qeue.addAll(getConnected(r));

			if(!runes.contains(r))
				runes.add(r);

		}

		return runes;
	}

	private static ArrayList<TileEntityMagicRune> getConnected(TileEntityMagicRune rune){

		ArrayList<TileEntityMagicRune> runes = new ArrayList<TileEntityMagicRune>();

		TileEntity tile = rune.worldObj.getBlockTileEntity(rune.xCoord + 1, rune.yCoord, rune.zCoord);

		if(tile != null && tile instanceof TileEntityMagicRune)
			runes.add((TileEntityMagicRune) tile);

		tile = rune.worldObj.getBlockTileEntity(rune.xCoord, rune.yCoord, rune.zCoord + 1);

		if(tile != null && tile instanceof TileEntityMagicRune)
			runes.add((TileEntityMagicRune) tile);

		tile = rune.worldObj.getBlockTileEntity(rune.xCoord - 1, rune.yCoord, rune.zCoord);

		if(tile != null && tile instanceof TileEntityMagicRune)
			runes.add((TileEntityMagicRune) tile);

		tile = rune.worldObj.getBlockTileEntity(rune.xCoord, rune.yCoord, rune.zCoord - 1);

		if(tile != null && tile instanceof TileEntityMagicRune)
			runes.add((TileEntityMagicRune) tile);

		return runes;
	}

	@Override
	public PowerPacket getPower() {
		return power;
	}

	@Override
	public void setPower(PowerPacket newPower) {
		power = newPower;

		for(TileEntityMagicRune r : runes)
			r.setPower(power.getAmount());
	}

	@Override
	public int getMaxPower() {
		return 50 * ratio;
	}

	public boolean equals(Object o){

		if(!(o instanceof MagicRunePowerHandeler) || o == null)
			return false;

		MagicRunePowerHandeler m = (MagicRunePowerHandeler) o;

		return m.runes.containsAll(runes) && runes.containsAll(m.runes);

	}

	@Override
	public boolean recievePower(PowerPacket newPower) {
		boolean b = power.merge(newPower);

		power.setToMaxIfNessecary(getMaxPower());

		for(TileEntityMagicRune r : runes)
			r.setPower(power.getAmount());

		return b;
	}

	public ArrayList<TileEntityMagicRune> getRunes() {
		return runes;
	}




}

@Override
	public boolean equals(Object o){

		if(!(o instanceof TileEntity))
			return false;

		TileEntity t = (TileEntity) o;

		return t.xCoord == xCoord && t.yCoord == yCoord && t.zCoord == zCoord;

	}

public void setPowerLevel(int i) {
	power = i * ratio;

}

public int getPowerLevel() {
	return (int) (power / ratio);
}

/**
 * Reads a tile entity from NBT.
 */
public void readFromNBT(NBTTagCompound nbt)
{
    super.readFromNBT(nbt);
    power = nbt.getInteger("Power");
}

/**
 * Writes a tile entity to NBT.
 */
public void writeToNBT(NBTTagCompound nbt)
{
    
	super.writeToNBT(nbt);
	nbt.setInteger("Power", power);

}

public void damage(int damage){
	power -= damage * ratio;
}

public boolean canPass(){
	return power <= 0;
}

public boolean isAtFullPower() {
	return getPowerLevel() >= 50;
}

public void setPower(int i) {
	power = i;

}

public int getPower() {
	return power;
}

public void onCreated() {

	for(ForgeDirection f : new ForgeDirection[] {ForgeDirection.NORTH, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.WEST}){

		TileEntity t = worldObj.getBlockTileEntity(xCoord + f.offsetX, yCoord, zCoord + f.offsetZ);

		if(t != null && t instanceof TileEntityMagicRune){
			TileEntityMagicRune r = (TileEntityMagicRune) t;

			if(r.getPower() >= this.getPower())
				power = r.getPower();
			else
				r.setPower(power);

		}

	}


}

}

 

 

Link to comment
Share on other sites

Hi

 

Block textures only update when there is a change.  When rendering Blocks, minecraft uses a 'cached renderlist'  that is only refreshed when the block changes.  So if you try to animate your Block using the Block rendering methods above, you won't see anything until the Block is changed or updated.

If you want your Block to be animated without updating it, you need to either use an animated texture for your Block, or use a TileEntity with TileEntitySpecialRender.

 

For more info see here

http://greyminecraftcoder.blogspot.com.au/2013/07/rendering-world-more-details-including.html

 

-TGG

Link to comment
Share on other sites

Actually all you have to do is update the block when you want the texture to change using

worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);

Just make sure you are also synchronising the client tile data with the server using

@Override
public Packet getDescriptionPacket() {
NBTTagCompound tagCompound = new NBTTagCompound();
this.writeToNBT(tagCompound);
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, tagCompound);
}

@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
readFromNBT(pkt.func_148857_g());
}

I am the author of Draconic Evolution

Link to comment
Share on other sites

I have the renderer, but the texture flickers, and sometimes disapears.

 

Here's my code:

Renderer:

 

 

package Technomage3.both.Renderers;

import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

import Technomage3.both.Blocks.tileentities.TileEntityMagicRune;
import Technomage3.both.Models.ModelMagicRune;

public class MagicRuneRenderer extends TileEntitySpecialRenderer {

@Override
public void renderTileEntityAt(TileEntity tileentity, double d0, double d1,
		double d2, float f) {
	renderRune((TileEntityMagicRune) tileentity, d0, d1, d2, f);

}

private void renderRune(TileEntityMagicRune tile, double x,
		double y, double z, float f) {

	Tessellator tessellator = Tessellator.instance;
    
	this.bindTexture(getTexture(tile.getPowerLevel()));
    GL11.glPushMatrix();
    GL11.glTranslated(x, y, z);
    tessellator.startDrawingQuads();
    
    tessellator.addVertexWithUV(0, 0, 0, 0, 0);
    tessellator.addVertexWithUV(0, 0, 1, 0, 1);
    tessellator.addVertexWithUV(1, 0, 1, 1, 1);
    tessellator.addVertexWithUV(1, 0, 0, 1, 0);

    tessellator.addVertexWithUV(0, 0, 0, 0, 0);
    tessellator.addVertexWithUV(1, 0, 0, 1, 0);
    tessellator.addVertexWithUV(1, 0, 1, 1, 1);
    tessellator.addVertexWithUV(0, 0, 1, 0, 1);
    
    tessellator.draw();
    GL11.glPopMatrix();

}

private ResourceLocation getTexture(int power) {

	if(power > 30){

		return icons[2];

	} else if(power > 0){

		return icons[1];

	} else{

		return icons[0];

	}

}

private ResourceLocation[] icons = new ResourceLocation[]{

		new ResourceLocation("tn3", "textures/blocks/magicRuneLow.png"),
		new ResourceLocation("tn3", "textures/blocks/magicRuneMid.png"),
		new ResourceLocation("tn3", "textures/blocks/magicRuneHigh.png")


};

}

 

 

Block:

 

 

package Technomage3.both.Blocks;

import java.util.Random;

import thaumcraft.common.config.ConfigBlocks;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import am2.AMCore;
import am2.blocks.BlocksCommonProxy;
import am2.particles.AMParticle;
import am2.particles.ParticleFloatUpward;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import Technomage3.Core.Blocks.TN3Block;
import Technomage3.Core.Blocks.TN3BlockContainer;
import Technomage3.Core.Utils.TN3Utils;
import Technomage3.both.Blocks.tileentities.TileEntityMagicRune;
import Technomage3.both.Power.IUsePower;

public class BlockMagicRune extends TN3BlockContainer {

private Icon[] icons = new Icon[3];

public BlockMagicRune(String realName, String unlocalizedName, CreativeTabs tab) {
	super(realName, unlocalizedName, tab);
	this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.01F, 1.0F);
	this.setLightOpacity(0);
	this.setTickRandomly(true);
}

public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
	return AxisAlignedBB.getAABBPool().getAABB((double)par2 + super.minX, (double)par3 + super.minY, (double)par4 + super.minZ, (double)par2 + super.maxX, (double)par3 + super.maxY, (double)par4 + super.maxZ);
}

public void setBlockBoundsForItemRender()
{
	this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.01F, 1.0F);
}


public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int meta, float hitX, float hitY, float hitZ)
{

	TileEntityMagicRune tile = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	if(!world.isRemote){
		player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(
				"Power Level: " + tile.getPowerLevel() + 
				", Power: " + tile.getPower()
				));
	}

	return true;
}

@Override
public TileEntity createNewTileEntity(World world) {
	return new TileEntityMagicRune();
}

public void randomDisplayTick(World world, int x, int y, int z, Random rand)
{
	if(world.isRemote && this.getPowerLevel(world, x, y, z) >= 50){

	} else if(world.isRemote && this.getPowerLevel(world, x, y, z) >= 0){


	} else{



	}
}

public int getPowerLevel(IBlockAccess world, int x, int y, int z) {

	TileEntityMagicRune tile = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	return tile.getPowerLevel();
}


/*
public Icon getIcon(int par1, int par2)
{
	return icons[1];
}
*/
public void registerIcons(IconRegister register)
{
	/*
	icons[2] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneHigh");

	icons[1] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneMid");

	icons[0] = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneLow");
	*/
	blockIcon = register.registerIcon(TN3Utils.getTexturePrefix() + "magicRuneMid");

}

public void onBlockAdded(World world, int x, int y, int z) {

	TileEntityMagicRune rune = (TileEntityMagicRune) world.getBlockTileEntity(x, y, z);

	rune.onCreated();

}

public static boolean isNormalCube(int par0)
{
	return false;
}

public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean renderAsNormalBlock()
    {
        return false;
    }

    public int getRenderType()
    {
        return -1;
    }


}

 

 

Link to comment
Share on other sites

You probably have z-fighting. That's when two textures are fighting to get rendered. You see stripes of both textures and they change if you move. You can fix that by changing the z-level.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

The redstone block just has a small hitbox, and the part of the texture you see is the transparant part of the texture.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • How to fix file server-1.20.1-20230612.114412-srg.jar  
    • Just a few months ago I was creating my own plugin for Minecraft 1.20.2 spigot that did the same thing, but the skins were not saved, if you can understand this code that I made a long time ago it may help you.   //This is a class method private static String APIRequest(String value, String url, String toSearch) { try { URL api = new URL(url + value); HttpURLConnection connection = (HttpURLConnection) api.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); for (String responseChar; (responseChar = reader.readLine()) != null; ) response.append(responseChar); reader.close(); JSONObject responseObject = new JSONObject(response.toString()); if (!toSearch.equals("id")) return responseObject .getJSONArray("properties") .getJSONObject(0) .getString("value"); else return responseObject.getString("id"); } else { AntiGianka.ConsoleMessage(ChatColor.RED, String.format( "Could not get %s. Response code: %s", ((toSearch.equals("id")) ? "UUID" : "texture"), responseCode )); } } catch (MalformedURLException error) { AntiGianka.ConsoleMessage(ChatColor.RED, "An error occurred while trying to access the URL. Error: " + error); } catch (IOException error) { AntiGianka.ConsoleMessage(ChatColor.RED, "An error occurred while attempting to connect to the URL. Error: " + error); } return ""; } //other class method private void SkinGetter() { String uuid; String textureCoded; if ((uuid = APIRequest(args[0], "https://api.mojang.com/users/profiles/minecraft/", "id")).isEmpty() || (textureCoded = APIRequest(uuid, "https://sessionserver.mojang.com/session/minecraft/profile/", "value")).isEmpty() ) sender.sendMessage(ChatColor.RED + String.format( "An error has occurred while trying to obtain the %s player skin, please check if the name %s is spelled correctly or try again later.", args[0], args[0] ) ); else SkinSetter(textureCoded); } //other more private void SkinSetter(String textureCoded) { JSONObject profile = new JSONObject(new String(Base64.getDecoder().decode(textureCoded))); try { URL textureUrl = new URL(profile.getJSONObject("textures"). getJSONObject("SKIN"). getString("url")); if (sender instanceof Player && args.length == 1) { PlayerTextures playerTextures = ((Player) sender).getPlayerProfile().getTextures(); playerTextures.setSkin(textureUrl); ((Player) sender).getPlayerProfile().setTextures(playerTextures); if (((Player) sender).getPlayerProfile().getTextures().getSkin() != null) sender.sendMessage(((Player) sender).getPlayerProfile().getTextures().getSkin().toString()); else sender.sendMessage("Null"); sender.sendMessage("Skin changed successfully.a"); } else { } AntiGianka.ConsoleMessage(ChatColor.GREEN, "Skin command executed successfully."); } catch (MalformedURLException error) { sender.sendMessage(ChatColor.RED + String.format( "An error has occurred while trying to obtain the %s player skin, please check if the name %s is spelled correctly or try again later.", args[0], args[0] ) ); AntiGianka.ConsoleMessage(ChatColor.RED, "An error occurred while trying to access the URL. Error: " + error); } }  
    • Use /locate structure The chat should show all available structures as suggestion For the Ancient City it is /locate structure ancient_city
    • So does it work without this mod? Did you test it with other builds?
  • Topics

×
×
  • Create New...

Important Information

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