Jump to content

[1.14.4]How to render a box(x, y, z) near a block


dyno

Recommended Posts

Hello!

I would like to render a box (lenght, width and depth gives in GUI), starting rendering it opposite the block, with TER (as buildcraft's quarry does that renders the box it will mine with laser texture). 

 

e.g.

x,y,z given in GUI*

TER will render, starting opposite the block, a box: y block high, x block wide and z block deep.

 

TER:

package com.olivemod.blocks.machine.active.miner;

import com.mojang.blaze3d.platform.GlStateManager;
import com.olivemod.utils.RenderModUtils;
import com.olivemod.utils.Reference.Reference;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class MinerTERender extends TileEntityRenderer<MinerTE> {

	private static final ResourceLocation TEXTURE_BEACON_BEAM = new ResourceLocation(Reference.MOD_ID, "textures/entity/beacon_beam.png");
	
	/**
	 * Render our TileEntity
	 */
	@Override
	public void render(final MinerTE tileEntityIn, final double x, final double y, final double z, final float partialTicks, final int destroyStage) {
		super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);

	    GlStateManager.alphaFunc(516, 0.1F);
	    this.bindTexture(TEXTURE_BEACON_BEAM);
	    GlStateManager.disableFog();
	    
	    GlStateManager.pushMatrix();
	    GlStateManager.translated(x - tileEntityIn.getPos().getX(), y- tileEntityIn.getPos().getY(), z - tileEntityIn.getPos().getZ());
	    Tessellator tessellator = Tessellator.getInstance();
	    BufferBuilder bufferbuilder = tessellator.getBuffer();
	    bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
	      
	    bufferbuilder.pos(x, y + 2, z).tex(1.0d, 2.0d).color(1f, 1f, 1f, 1.0f).endVertex();
	    tessellator.draw();
	    GlStateManager.enableBlend();
	    GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
	    GlStateManager.depthMask(false);
	    GlStateManager.popMatrix();
	    GlStateManager.enableLighting();
	    GlStateManager.enableTexture();
	    GlStateManager.depthMask(true);
		GlStateManager.enableFog();
	}
	
	@Override
	public boolean isGlobalRenderer(MinerTE te) {
		// TODO Auto-generated method stub
		return true;
	}
}

 

TE:

package com.olivemod.blocks.machine.active.miner;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.olivemod.blocks.machine.passive.generator.MachineType;
import com.olivemod.energy.SeattableEnergyStorage.SettableEnergyStorage;
import com.olivemod.init.BlockInit;
import com.olivemod.init.ItemInit;
import com.olivemod.utils.ModTileEntityTypes;
import com.olivemod.utils.Reference.NBTKeys;

import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.extensions.IForgeTileEntity;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;

public class MinerTE extends TileEntity implements ITickableTileEntity, INamedContainerProvider
{
	private BlockPos invBlockPos = getPos().offset(Direction.UP);
	public int cookTime;
	public boolean canGo;
	public int x;
	public int y;
	public int z;
	public boolean fill;
	

	final SettableEnergyStorage storage = new SettableEnergyStorage(MachineType.MINER.getCapacity(), MachineType.MINER.getMaxIn(), 0);
	private final LazyOptional<IEnergyStorage> lazyOptionalEnergy = LazyOptional.of( () -> this.storage);
	
	public final ItemStackHandler inventory = new ItemStackHandler(6)
	{
		public boolean isItemValid(int slot, ItemStack stack) {
			return (stack.getItem() == ItemInit.IRON_OVERCLOCK.get() && slot == 0 )|| (stack.getItem() == ItemInit.GOLD_OVERCLOCK.get() && slot == 1 )|| 
					(stack.getItem() == ItemInit.DIAMOND_OVERCLOCK.get() && slot == 2 )|| (stack.getItem() == ItemInit.IRON_FORTUNE.get() && slot == 3 )|| 
					(stack.getItem() == ItemInit.GOLD_FORTUNE.get() && slot == 4 )|| (stack.getItem() == ItemInit.DIAMOND_FORTUNE.get() && slot == 5 ); 
		 
		};
	};

	public MinerTE(TileEntityType<?> tileEntityTypeIn) {
		super(tileEntityTypeIn);
		// TODO Auto-generated constructor stub
	}
	
	public MinerTE() {
		super(ModTileEntityTypes.MINER.get());
	}

	private int getSpeed()
	{
		for (int i = 0; i < 3; i++)
		{
			if (this.inventory.getStackInSlot(i).isEmpty())
			{
				return 100 - 25*i;
			}
		}
		return 100;	
	}
	
	private int getFortune()
	{
		for (int i = 0; i < 3; i++)
		{
			if (this.inventory.getStackInSlot(3 + i).isEmpty())
			{
				return i == 0 ? 1 : 5*i;
			}
		}
		return 1;		
	}
	
	@Override
	public void tick()
	{

		if (canMine())
		{
			BlockPos currentExcavation = getPos();
			
			for (int y = 0; y < this.y; y++)
			{
				for (int z = 0; z < this.z; z++)
				{
					for (int x = 0; x < this.x; x++)
					{
						currentExcavation.add(+x, -y, +z);
						BlockState blockState = world.getBlockState(currentExcavation);
						if ( blockState.getBlock() != Blocks.AIR)
						{
							if (world.getTileEntity(invBlockPos).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null) != null)
							{
								IItemHandler inventory = world.getTileEntity(invBlockPos).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
								for (int i = 0; i < inventory.getSlots(); i++)
								{
									ItemStack itemStack = new ItemStack(blockState.getBlock());
									if(inventory.getStackInSlot(i).getItem() == itemStack.getItem() && inventory.getStackInSlot(i).getCount() + itemStack.getCount() <= 64)
									{
										int consume =  (-(-100 + getSpeed())) * getFortune();
										while (cookTime < getSpeed())
										{
											cookTime++;
										}
										world.setBlockState(currentExcavation, Blocks.AIR.getDefaultState(), 2);
										inventory.insertItem(i, itemStack, false);
										cookTime = 0;
										this.storage.setEnergy(this.storage.getEnergyStored() - consume);
										this.markDirty();
										world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2);
									}
								}
							}
						}
					}
				}
			}
		}
		
	}
	
	private boolean canMine() {
		// TODO Auto-generated method stub
		return this.storage.getEnergyStored() > -(-100 + getSpeed());
	}

	@Override
	public <T> LazyOptional<T> getCapability(Capability<T> cap) {

		return cap == CapabilityEnergy.ENERGY ?  this.lazyOptionalEnergy.cast() : super.getCapability(cap);
	}
	
	@Override
	public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {

		this.storage.setEnergy(pkt.getNbtCompound().getInt(NBTKeys.ENERGY.getKey()));
	}
	
	@Override
	public void onLoad() {
		// TODO Auto-generated method stub
		super.onLoad();
	}
	
	@Override
	public void remove() {
		// TODO Auto-generated method stub
		super.remove();
		this.lazyOptionalEnergy.invalidate();
	}
	
	@Override
	public void read(CompoundNBT compound) {

		super.read(compound);
		this.storage.setEnergy(compound.getInt(NBTKeys.ENERGY.getKey()));
		this.inventory.deserializeNBT(compound);
		this.x = compound.getInt("x");
		this.y = compound.getInt("y");
		this.z = compound.getInt("z");
	}
	
	@Override
	public CompoundNBT write(CompoundNBT compound) {

		compound = super.write(compound);
		compound.putInt(NBTKeys.ENERGY.getKey(), this.storage.getEnergyStored());
		compound.put(NBTKeys.INVENTORY.getKey(), this.inventory.serializeNBT());
		compound.putInt("x", this.x);
		compound.putInt("y", this.y);
		compound.putInt("z", this.z);
		return compound;
	}
	
	/*
	 * Retrieves packet to send to the client whenever this Tile Entity is re-sinced via World#notifyBlockUpdate. 
	 * This packet comes back client-side via (@link #onDataPacket)
	 */
	@Nullable
	public SUpdateTileEntityPacket getUpdatePacket() {

		final CompoundNBT tag = new CompoundNBT();
		tag.putInt(NBTKeys.ENERGY.getKey(), this.storage.getEnergyStored());
		tag.put(NBTKeys.INVENTORY.getKey(), this.inventory.serializeNBT());
		tag.putInt("x", this.x);
		tag.putInt("y", this.y);
		tag.putInt("z", this.z);
		//We pass 0 for TileEntityTypesIn because we have a modded TE.See ClientPlayNetHandler#handlerUpdateTileEntity(SUpdateTileEntityPacket)
		return new SUpdateTileEntityPacket(this.pos, 0, tag);
	}
	
	
	/*
	 * Get an NBT compount to sync to the client with SPacketChunkData, used to initial loading of the chunk or when many blocks change at once
	 * This compound comes back to the client-side in (@link #handleUpdateTag)
	 * The default implementation ({@link TileEntity#handleUpdateTag}) calls {@link #writeInternal)}
	 * wich doesn't save any of our extra data so we override it to call {@link #write} instead 
	 */
	@Nonnull
	public CompoundNBT getUpdateTag() {

		return this.write(new CompoundNBT());
	}

	@Override
	public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) {
		// TODO Auto-generated method stub
		return new MinerContainer(p_createMenu_1_, p_createMenu_2_, this);
	}

	@Override
	public ITextComponent getDisplayName() {
		// TODO Auto-generated method stub
		return BlockInit.MINER.get().getNameTextComponent();
	}

	@Override
	public AxisAlignedBB getRenderBoundingBox() {

		return IForgeTileEntity.INFINITE_EXTENT_AABB;
	}
}

 

I have never used TER before. I cannot find docs for each method that GlStateManager provides. But I have only understood something about pushMatrix() and popMatrix().

I just took a look at BeaconTER.

I have registered TER in FMLClient, yet.

Link to comment
Share on other sites

Well, in the beacon TER there should be everything you need to understand in order to render simple geometry, like a box. Also I think you will find this example useful: https://github.com/TheGreyGhost/MinecraftByExample/tree/1-14-4-partial/src/main/java/minecraftbyexample/mbe21_tileentityspecialrenderer

Edited by Beethoven92

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Link to comment
Share on other sites

49 minutes ago, Beethoven92 said:

Well, in the beacon TER there should be everything you need to understand in order to render simple geometry, like a box. Also I think you will find this example useful: https://github.com/TheGreyGhost/MinecraftByExample/tree/1-14-4-partial/src/main/java/minecraftbyexample/mbe21_tileentityspecialrende

To understand better it, I tried to draw the Beacon segment (Just one block) on the miner. Nothing appear. 

I bilieve to have registered TER wrong.

And I have not still understood GlSM methods what do

Link to comment
Share on other sites

17 minutes ago, dyno said:

To understand better it, I tried to draw the Beacon segment (Just one block) on the miner. Nothing appear. 

I bilieve to have registered TER wrong.

And I have not still understood GlSM methods what do

I registered with ClientRegistry#bindTESR in a private void (final FMLClientSetupEvent) and this method Is called via a final IEventBus.addListener

Link to comment
Share on other sites

8 minutes ago, Beethoven92 said:

Thats a possibility, show the rest of your code please

TER(edited after have read link you showed):

package com.olivemod.blocks.machine.active.miner;

import org.lwjgl.opengl.GL11;

import com.mojang.blaze3d.platform.GlStateManager;
import com.olivemod.Main;
import com.olivemod.utils.Reference.Reference;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class MinerTERender extends TileEntityRenderer<MinerTE> {

	MinerTE minerTE;
	private static final ResourceLocation TEXTURE = new ResourceLocation(Reference.MOD_ID, "textures/entity/beacon_beam.png");
	public MinerTERender() {
		Main.LOGGER.info("MinerTERender called");
	}
	/*
	 * Render the TE - called every frame while that block is in view of the player
	 * 
	 * @param tileEntityIn - is the TE associated to the block
	 * @param x - the X distance from the player
	 * @param y - the Y distance from the player
	 * @param z - the Z distance from the player
	 * @param partialTicks - the fraction of a ticks that this frame is being renderd at - 
	 * e.g.
	 * if it is 80, then this method will be called 4 times at second => 20 ticks are 1 sec, then 20/80 = 0.25 sec
	 * 
	 * @param destroyStage - the progress of the block being damaged (0-10) if relevant, -1 if not
	 */
	@Override
	public void render(MinerTE tileEntityIn, double x, double y, double z, float partialTicks, int destroyStage) {

		Minecraft.getInstance().player.sendChatMessage("Render");
		//This should never happens
		if (!(tileEntityIn instanceof MinerTE))
		{
			Minecraft.getInstance().player.sendChatMessage("No Way");
			return;
		}
		
		this.minerTE = tileEntityIn;
		
		/*
		 * This TER renders a box that begins from the opposite side of the miner
		 * Height, Depth and Length are given by player in the GUI
		 * 
		 * The box rendered contains all the blocks that miner will mine 
		 */
		
		try {
			/* save the transformation matrix and the rendering attributes, so that we can restore them after rendering.  This
			*  prevents us disrupting any vanilla TESR that render after ours.
			*  using try..finally is not essential but helps make it more robust in case of exceptions
			*  For further information on rendering using the Tessellator, see http://greyminecraftcoder.blogspot.co.at/2014/12/the-tessellator-and-worldrenderer-18.html
			*/
			GL11.glPushMatrix();
			GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
			
			/* First we need to set up the translation so that we render our box with the bottom point at 0,0,0
			/* when the renderTileEntityAt method is called, the tessellator is set up so that drawing a dot at [0,0,0] corresponds to the player's eyes
			*/
			GlStateManager.translated(x + 0.5d,  y + 2.5d, z + 0.5d);
			
			Tessellator tessellator = Tessellator.getInstance();
			BufferBuilder bufferBuilder = tessellator.getBuffer();
			Minecraft.getInstance().player.sendChatMessage("Building");
			this.bindTexture(TEXTURE);
			
			//Set the key rendering flags appropriately...
			//GL11.glDisable(GL11.GL_LIGHTING);	//Turn off "item" lighting 
			//GL11.glDisable(GL11.GL_BLEND);		//Turn off "alpha" transparency blending
			//GL11.glDepthMask(false);			//it is hidden behind other objects
			
			bufferBuilder.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX);
			tessellator.draw();
			
		} finally {
			GL11.glPopAttrib();
			GL11.glPopMatrix();
			Minecraft.getInstance().player.sendChatMessage("OK");
		}
	}
	
	@Override
	public boolean isGlobalRenderer(MinerTE te) {
		// TODO Auto-generated method stub
		return false;
	}
}

 

TE:

package com.olivemod.blocks.machine.active.miner;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.olivemod.blocks.machine.passive.generator.MachineType;
import com.olivemod.energy.SeattableEnergyStorage.SettableEnergyStorage;
import com.olivemod.init.BlockInit;
import com.olivemod.init.ItemInit;
import com.olivemod.utils.ModTileEntityTypes;
import com.olivemod.utils.Reference.NBTKeys;

import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.extensions.IForgeTileEntity;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;

public class MinerTE extends TileEntity implements ITickableTileEntity, INamedContainerProvider
{
	private BlockPos invBlockPos = getPos().offset(Direction.UP);
	public int cookTime;
	public boolean canGo;
	public int x;
	public int y;
	public int z;
	public boolean fill;
	

	final SettableEnergyStorage storage = new SettableEnergyStorage(MachineType.MINER.getCapacity(), MachineType.MINER.getMaxIn(), 0);
	private final LazyOptional<IEnergyStorage> lazyOptionalEnergy = LazyOptional.of( () -> this.storage);
	
	public final ItemStackHandler inventory = new ItemStackHandler(6)
	{
		public boolean isItemValid(int slot, ItemStack stack) {
			return (stack.getItem() == ItemInit.IRON_OVERCLOCK.get() && slot == 0 )|| (stack.getItem() == ItemInit.GOLD_OVERCLOCK.get() && slot == 1 )|| 
					(stack.getItem() == ItemInit.DIAMOND_OVERCLOCK.get() && slot == 2 )|| (stack.getItem() == ItemInit.IRON_FORTUNE.get() && slot == 3 )|| 
					(stack.getItem() == ItemInit.GOLD_FORTUNE.get() && slot == 4 )|| (stack.getItem() == ItemInit.DIAMOND_FORTUNE.get() && slot == 5 ); 
		 
		};
	};

	public MinerTE(TileEntityType<?> tileEntityTypeIn) {
		super(tileEntityTypeIn);
		// TODO Auto-generated constructor stub
	}
	
	public MinerTE() {
		super(ModTileEntityTypes.MINER.get());
	}

	private int getSpeed()
	{
		for (int i = 0; i < 3; i++)
		{
			if (this.inventory.getStackInSlot(i).isEmpty())
			{
				return 100 - 25*i;
			}
		}
		return 100;	
	}
	
	private int getFortune()
	{
		for (int i = 0; i < 3; i++)
		{
			if (this.inventory.getStackInSlot(3 + i).isEmpty())
			{
				return i == 0 ? 1 : 5*i;
			}
		}
		return 1;		
	}
	
	@Override
	public void tick()
	{

		if (canMine())
		{
			BlockPos currentExcavation = getPos();
			
			for (int y = 0; y < this.y; y++)
			{
				for (int z = 0; z < this.z; z++)
				{
					for (int x = 0; x < this.x; x++)
					{
						currentExcavation.add(+x, -y, +z);
						BlockState blockState = world.getBlockState(currentExcavation);
						if ( blockState.getBlock() != Blocks.AIR)
						{
							if (world.getTileEntity(invBlockPos).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null) != null)
							{
								IItemHandler inventory = world.getTileEntity(invBlockPos).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
								for (int i = 0; i < inventory.getSlots(); i++)
								{
									ItemStack itemStack = new ItemStack(blockState.getBlock());
									if(inventory.getStackInSlot(i).getItem() == itemStack.getItem() && inventory.getStackInSlot(i).getCount() + itemStack.getCount() <= 64)
									{
										int consume =  (-(-100 + getSpeed())) * getFortune();
										while (cookTime < getSpeed())
										{
											cookTime++;
										}
										world.setBlockState(currentExcavation, Blocks.AIR.getDefaultState(), 2);
										inventory.insertItem(i, itemStack, false);
										cookTime = 0;
										this.storage.setEnergy(this.storage.getEnergyStored() - consume);
										this.markDirty();
										world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2);
									}
								}
							}
						}
					}
				}
			}
		}
		
	}
	
	private boolean canMine() {
		// TODO Auto-generated method stub
		return this.storage.getEnergyStored() > -(-100 + getSpeed());
	}

	@Override
	public <T> LazyOptional<T> getCapability(Capability<T> cap) {

		return cap == CapabilityEnergy.ENERGY ?  this.lazyOptionalEnergy.cast() : super.getCapability(cap);
	}
	
	@Override
	public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {

		this.storage.setEnergy(pkt.getNbtCompound().getInt(NBTKeys.ENERGY.getKey()));
	}
	
	@Override
	public void onLoad() {
		// TODO Auto-generated method stub
		super.onLoad();
	}
	
	@Override
	public void remove() {
		// TODO Auto-generated method stub
		super.remove();
		this.lazyOptionalEnergy.invalidate();
	}
	
	@Override
	public void read(CompoundNBT compound) {

		super.read(compound);
		this.storage.setEnergy(compound.getInt(NBTKeys.ENERGY.getKey()));
		this.inventory.deserializeNBT(compound);
		this.x = compound.getInt("x");
		this.y = compound.getInt("y");
		this.z = compound.getInt("z");
	}
	
	@Override
	public CompoundNBT write(CompoundNBT compound) {

		compound = super.write(compound);
		compound.putInt(NBTKeys.ENERGY.getKey(), this.storage.getEnergyStored());
		compound.put(NBTKeys.INVENTORY.getKey(), this.inventory.serializeNBT());
		compound.putInt("x", this.x);
		compound.putInt("y", this.y);
		compound.putInt("z", this.z);
		return compound;
	}
	
	/*
	 * Retrieves packet to send to the client whenever this Tile Entity is re-sinced via World#notifyBlockUpdate. 
	 * This packet comes back client-side via (@link #onDataPacket)
	 */
	@Nullable
	public SUpdateTileEntityPacket getUpdatePacket() {

		final CompoundNBT tag = new CompoundNBT();
		tag.putInt(NBTKeys.ENERGY.getKey(), this.storage.getEnergyStored());
		tag.put(NBTKeys.INVENTORY.getKey(), this.inventory.serializeNBT());
		tag.putInt("x", this.x);
		tag.putInt("y", this.y);
		tag.putInt("z", this.z);
		//We pass 0 for TileEntityTypesIn because we have a modded TE.See ClientPlayNetHandler#handlerUpdateTileEntity(SUpdateTileEntityPacket)
		return new SUpdateTileEntityPacket(this.pos, 0, tag);
	}
	
	
	/*
	 * Get an NBT compount to sync to the client with SPacketChunkData, used to initial loading of the chunk or when many blocks change at once
	 * This compound comes back to the client-side in (@link #handleUpdateTag)
	 * The default implementation ({@link TileEntity#handleUpdateTag}) calls {@link #writeInternal)}
	 * wich doesn't save any of our extra data so we override it to call {@link #write} instead 
	 */
	@Nonnull
	public CompoundNBT getUpdateTag() {

		return this.write(new CompoundNBT());
	}

	@Override
	public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) {
		// TODO Auto-generated method stub
		return new MinerContainer(p_createMenu_1_, p_createMenu_2_, this);
	}

	@Override
	public ITextComponent getDisplayName() {
		// TODO Auto-generated method stub
		return BlockInit.MINER.get().getNameTextComponent();
	}

	@Override
	public AxisAlignedBB getRenderBoundingBox() {

		return IForgeTileEntity.INFINITE_EXTENT_AABB;
	}
	
	@Override
	public double getMaxRenderDistanceSquared() {

		return 32;
	}
}

Main:

package com.olivemod;

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

import com.olivemod.blocks.machine.active.flour_mill.FlourMillTE;
import com.olivemod.blocks.machine.active.flour_mill.FlourMillTER;
import com.olivemod.blocks.machine.active.miner.MinerTE;
import com.olivemod.blocks.machine.active.miner.MinerTERender;
import com.olivemod.event.generation.OreGeneration;
import com.olivemod.event.generation.tree.TreeGeneration;
import com.olivemod.fluid.Fluids;
import com.olivemod.init.BlockInit;
import com.olivemod.init.ItemInit;
import com.olivemod.proxy.StartupClientOnly;
import com.olivemod.utils.ModContainerTypes;
import com.olivemod.utils.ModTileEntityTypes;
import com.olivemod.utils.Reference.Reference;

import net.minecraft.item.crafting.ShapedRecipe;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

@Mod(Reference.MOD_ID)
@Mod.EventBusSubscriber(modid = Reference.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class Main
{
	
	public static Main instance;
	
	// Directly reference a log4j logger.
    public static final Logger LOGGER = LogManager.getLogger();
    
   public Main() {
	
	   	LOGGER.debug("Welcome from OliveMod");	   
	   	@SuppressWarnings("unused")
		final ModLoadingContext modLoadingContext = ModLoadingContext.get();
	   
	   	/*
	   	 * @modEventBus register the setup method for modLoading
	   	 * @modEventBus register the initClient method for modLoading
	   	 */
	   	final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
		modEventBus.addListener(this::setup);
//		modEventBus.addListener(this::initClient);


		ItemInit.ITEM.register(modEventBus);
		BlockInit.BLOCK.register(modEventBus);
		ModContainerTypes.CONTAINER_TYPE.register(modEventBus);
		ModTileEntityTypes.TILE_ENTITY_TYPE.register(modEventBus);
		Fluids.FLUIDS.register(modEventBus);

		instance = this;
		MinecraftForge.EVENT_BUS.register(this);
		modEventBus.register(StartupClientOnly.class);
   }
   

	public  void setup(final FMLCommonSetupEvent event) {// K9#8016
		
		OreGeneration.oreGeneration();
		TreeGeneration.init();
		//CapabilityManager.INSTANCE.register(IThirsty.class, new ThirstyStorage(), Thirsty::new);
		ShapedRecipe.setCraftingSize(5, 5);
	}
	
}

StartupClientOnly:

package com.olivemod.proxy;

import com.olivemod.blocks.machine.active.miner.MinerTE;
import com.olivemod.blocks.machine.active.miner.MinerTERender;

import net.minecraftforge.fml.client.registry.ClientRegistry;

public class StartupClientOnly
{

	public static void preInitClientOlny()
	{
		
	}
	
	public static void initClientOlny()
	{
		ClientRegistry.bindTileEntitySpecialRenderer(MinerTE.class, new MinerTERender());
	}
	
	public static void postInitClientOlny()
	{
		
	}
}

 

Link to comment
Share on other sites

You did not specify the event to which your listener listens to...you need to do the same you did for this method:

public void setup(final FMLCommonSetupEvent event)

and change the listened event to FMLClientSetupEvent...the other two methods, preInit and postInit, do not serve a purpose anymore, you won't need those. Also, its true that you have registered the StartupClientOnly class, but the methods that listen to events inside that class still need to be annotated with @SubscribeEvent. Also, where is this method in your code?

modEventBus.addListener(this::initClient);

 

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

Link to comment
Share on other sites

25 minutes ago, Beethoven92 said:

You did not specify the event to which your listener listens to...you need to do the same you did for this method:


public void setup(final FMLCommonSetupEvent event)

and change the listened event to FMLClientSetupEvent...the other two methods, preInit and postInit, do not serve a purpose anymore, you won't need those. Also, its true that you have registered the StartupClientOnly class, but the methods that listen to events inside that class still need to be annotated with @SubscribeEvent. Also, where is this method in your code?


modEventBus.addListener(this::initClient);

 

@SubscribeEvent added. Now tua messages appear in chat. Anyway the Beacon beam (for Just One block) doesn't appear. Error in TER code sure?

25 minutes ago, Beethoven92 said:

modEventBus.addListener(this::initClient);

I deleted this when I took a look at the link you gave me

Link to comment
Share on other sites

Quote

Anyway the Beacon beam (for Just One block) doesn't appear. Error in TER code sure?

Well, at the moment there is nothing in your TER render code that tells the game to render something. Thats why i suggested you to look at how the beacon renderer draw the beam, you just need to copy that code. Also in the link to the example mod i posted earlier (in the TER class) there is code that draws a geometrical form on the screen. Take a better look at the code and see if you can figure it out and adapt to your needs

Check out the port of the BetterEnd fabric mod (WIP): https://www.curseforge.com/minecraft/mc-mods/betterend-forge-port

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.