Jump to content

Recommended Posts

Posted

Some days ago I begun modding 1.14.4. I made a block with a tile entity and a container. But when I try to open GUI, nothing happens and no errors appear in console.

I am follow Cadiboo's guide, I just change the register method(just wrote in the class of block) and it works, but not for tile entity.

I tried to push item with a hopper and it doesn't take. Blockstate json missing for block 

 

Block

package com.olivemod.energy.generator.glowstone_generator;

import java.io.Console;

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

import com.google.common.base.Preconditions;
import com.mojang.datafixers.DataFix;
import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.datafixers.types.Type;
import com.olivemod.init.BlockInit;
import com.olivemod.init.ModItemGroups;
import com.olivemod.utils.ModTileEntityTypes;
import com.olivemod.utils.Reference;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HopperBlock;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.HopperTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.Mirror;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.SharedConstants;
import net.minecraft.util.datafix.DataFixesManager;
import net.minecraft.util.datafix.TypeReferences;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.ToolType;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistryEntry;
import net.minecraftforge.registries.RegistryBuilder;

@EventBusSubscriber(modid = Reference.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class GlowStoneGenerator extends HorizontalBlock{

	protected static ItemGroup itemGroup;
	protected static String name;
	protected static Properties properties = Block.Properties.create(Material.IRON);
	protected static Block block;
	
	public GlowStoneGenerator(final String name, final ItemGroup itemGroup) {

		super(properties);			
		this.setDefaultState(this.getDefaultState().with(HORIZONTAL_FACING, Direction.NORTH));
		
		GlowStoneGenerator.name = name;
		GlowStoneGenerator.itemGroup = itemGroup;
		GlowStoneGenerator.block = new Block(properties).setRegistryName(new ResourceLocation(Reference.MOD_ID, name));;
	}	
	
	@SubscribeEvent
	public static void onRegisterBlock(RegistryEvent.Register<Block> event) {
		
		event.getRegistry().register(block);
	}
	
	@SubscribeEvent
	public static void onRegisterBlockItem(RegistryEvent.Register<Item> event) {
		
		event.getRegistry().register(new BlockItem(block, new Item.Properties().group(itemGroup)).setRegistryName(new ResourceLocation(Reference.MOD_ID, name)));
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {

		if(state != newState)
		{
			TileEntity tileEntity = worldIn.getTileEntity(pos);
			if(tileEntity instanceof TileEntityGlowStoneGenerator)
			{
				final ItemStackHandler inventory = ((TileEntityGlowStoneGenerator) tileEntity).inventory;
				for(int i = 0; i < inventory.getSlots(); i++)
				{
					InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), inventory.getStackInSlot(i));
				}
			}
		}
		super.onReplaced(state, worldIn, pos, newState, isMoving);
	}
	
	@Override
	public boolean onBlockActivated( final BlockState state, final World worldIn, final BlockPos pos, final PlayerEntity player, final Hand handIn, final BlockRayTraceResult hit) {

		System.out.print("Block Activated");
		LOGGER.debug("Activated");
		if(!worldIn.isRemote)
		{
			System.out.print("Client");
			final TileEntity tileEntity = worldIn.getTileEntity(pos);
			if(tileEntity instanceof TileEntityGlowStoneGenerator)
			{
				NetworkHooks.openGui((ServerPlayerEntity) player, (TileEntityGlowStoneGenerator)tileEntity, pos);
				System.out.print("Open");
			}
		}
		return true;
	}
	
	//Make block faces player
	@Override
	public BlockState getStateForPlacement(BlockItemUseContext context) {

		return this.getDefaultState().with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite());
	}
	
	
	//return redstone value calculated from inventory
	@SuppressWarnings("deprecation")
	@Override
	public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) {

		final TileEntity tileEntity = worldIn.getTileEntity(pos);
		if(tileEntity instanceof TileEntityGlowStoneGenerator)
		{
			return ItemHandlerHelper.calcRedstoneFromInventory(((TileEntityGlowStoneGenerator)tileEntity).inventory);
		}
		return super.getComparatorInputOverride(blockState, worldIn, pos);
	}
	
	
	//Called from constructor	//Add all properties to blockstate
	@Override	
	protected void fillStateContainer(Builder<Block, BlockState> builder) {
		
		super.fillStateContainer(builder);
		builder.add(HORIZONTAL_FACING);
	}
	
	
	//return the blockstate with the given rotation from blockstate passed
	@Override
	public BlockState rotate(BlockState state, Rotation rot) {

		return state.with(HORIZONTAL_FACING, state.get(HORIZONTAL_FACING));
	}
	
	
	//return the blockstate with the given mirror from blockstate passed
	@Override
	public BlockState mirror(BlockState state, Mirror mirrorIn) {

		return state.rotate(mirrorIn.toRotation(state.get(HORIZONTAL_FACING)));
	}
	
	@Override
	public TileEntity createTileEntity(BlockState state, IBlockReader world) {

		return ModTileEntityTypes.GLOWSTONE_GENERATOR_TILE_ENTITY.create();
	}
	
	@Override
	public boolean hasTileEntity(BlockState state) {
		// TODO Auto-generated method stub
		return true;
	}
	
	/**
	 * This method will be called by Forge when it is time for the mod to register its TileEntityType.
	 * This method will always be called after the Block and Item registry methods.
	 */
	@SubscribeEvent
	public static void onRegisterTileEntityTypes(@Nonnull final RegistryEvent.Register<TileEntityType<?>> event) {
		// Register your TileEntityTypes here if you have them
		event.getRegistry().registerAll(
				// We don't have a datafixer for our TileEntity, so we pass null into build
				setup(TileEntityType.Builder.create(TileEntityGlowStoneGenerator::new, BlockInit.GLOWSTONE_GENERATOR).build(null), "glowstone_generator")

		);
		LOGGER.debug("Registered TileEntityTypes");
	}

	/**
	 * This method will be called by Forge when it is time for the mod to register its ContainerTypes.
	 * This method will always be called after the Block and Item registry methods.
	 */
	@SubscribeEvent
	public static void onRegisterContainerTypes(@Nonnull final RegistryEvent.Register<ContainerType<?>> event) {
		// Register your ContainerTypes here if you have them
		event.getRegistry().registerAll(
				setup(IForgeContainerType.create(GlowStoneGeneratorContainer::new), "heat_collector")
		);
		LOGGER.debug("Registered ContainerTypes");
	}


	/**
	 * Performs setup on a registry entry
	 *
	 * @param name The path of the entry's name. Used to make a name who's domain is our mod's modid
	 */
	@Nonnull
	private static <T extends IForgeRegistryEntry<T>> T setup(@Nonnull final T entry, @Nonnull final String name) {
		Preconditions.checkNotNull(name, "Name to assign to entry cannot be null!");
		return setup(entry, new ResourceLocation(Reference.MOD_ID, name));
	}

	/**
	 * Performs setup on a registry entry
	 *
	 * @param registryName The full registry name of the entry
	 */
	@Nonnull
	private static <T extends IForgeRegistryEntry<T>> T setup(@Nonnull final T entry, @Nonnull final ResourceLocation registryName) {
		Preconditions.checkNotNull(entry, "Entry cannot be null!");
		Preconditions.checkNotNull(registryName, "Registry name to assign to entry cannot be null!");
		entry.setRegistryName(registryName);
		return entry;
	}


}

 

TileEntity

package com.olivemod.energy.generator.glowstone_generator;

import javax.annotation.Nonnull;

import com.olivemod.energy.SeattableEnergyStorage.SettableEnergyStorage;
import com.olivemod.init.BlockInit;
import com.olivemod.utils.ModTileEntityTypes;
import com.sun.istack.internal.Nullable;

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.ItemStack;
import net.minecraft.item.Items;
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.util.Direction;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.EnergyStorage;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;

public class TileEntityGlowStoneGenerator extends TileEntity implements ITickableTileEntity, INamedContainerProvider {

	public static final int INPUT_SLOT = 0;
	public static final int OUTPUT_SLOT = 1;
	
	private int cookTime;

	private static final String INVENTORY_TAG = "inventory";
	private static final String SMELT_TIME_LEFT_TAG = "smeltTimeLeft";
	private static final String MAX_SMELT_TIME_TAG = "maxSmeltTime";
	private static final String ENERGY_TAG = "energy";
	
	public final ItemStackHandler inventory = new ItemStackHandler(2){
		
		public boolean isItemValid(int slot, net.minecraft.item.ItemStack stack) {
			if(slot == INPUT_SLOT)
				return getEnergyFromItem(stack) > 0;
			else if(slot == OUTPUT_SLOT)
				return stack.getCapability(CapabilityEnergy.ENERGY) != null;
			
			return false;
		};
		
		protected void onContentsChanged(int slot) {
			
			super.onContentsChanged(slot);
			//Make the tile entiy as having changed whenever its inventory changes
			//"markDirty()" tells game the chunk contaong tile entity has changed and it will save to disk later
			TileEntityGlowStoneGenerator.this.markDirty();
		}
	};
	
	public final SettableEnergyStorage energy = new SettableEnergyStorage(10000, 0, 1000);
	
	//Store the capability lazy optionals as field to keep the amout of object we use to a minium 
	private final LazyOptional<ItemStackHandler> inventoryCapabilities = LazyOptional.of(() -> this.inventory);
	//Hoppers and Duct can connect to this generator's top to extract/insert items from Input Slot
	private final LazyOptional<IItemHandlerModifiable> InventorycapabilitiesUpAndSides = LazyOptional.of(() -> new RangedWrapper(inventory, INPUT_SLOT, INPUT_SLOT+1));
	//Hoppers and duct can connect to this generator's bottom to extract/insert items from Output Slot
	private final LazyOptional<IItemHandlerModifiable> InventoryCapabilitiesDown = LazyOptional.of(() -> new RangedWrapper(inventory, OUTPUT_SLOT, OUTPUT_SLOT+1));
	//Duct can connect to all side to extract energy
	private final LazyOptional<EnergyStorage> energyCapabilitiesExternal = LazyOptional.of(() -> this.energy);
	
	public short smeltTimeLeft = -1;
	public short maxSmeltTime = -1;
	@SuppressWarnings("unused")
	private int lastEnergy = -1;
	
	public TileEntityGlowStoneGenerator() {
		
		super(ModTileEntityTypes.GLOWSTONE_GENERATOR_TILE_ENTITY); 
	}

	@Override
	public void tick() {
		
		if(world == null && world.isRemote)
			return;
		
		//This method will push out energy passing it to a wire/machine
		outputEnergy();
		produceEnergy();
	}

	private void produceEnergy() {
		
		if(energy.getEnergyStored() < energy.getMaxEnergyStored())
		{
			ItemStack input = inventory.getStackInSlot(0);
			if(!input.isEmpty() && getEnergyFromItem(input) > 0)
			{		
				cookTime++;
				if(cookTime >= 25)
				{
					input.shrink(1);
					energy.receiveEnergy(getEnergyFromItem(input), false);
					//let vanilla update chunk
					this.markDirty();	
					//Notify client of a block update
					//This will result in the packet from getUpdatePacket beong sent to the client
					//Energy will be synced
					//Flag 2 send change to client
					world.notifyBlockUpdate(pos, this.getBlockState(), this.getBlockState(), 2);
					//Update the last energy to the current
					lastEnergy = energy.getEnergyStored();
				}
			}
		}
	}

	private int getEnergyFromItem(ItemStack input) {

		if(input.getItem() == Items.GLOWSTONE_DUST)
			return 200;
		else if(input.getItem() == Items.GLOWSTONE)
			return 1800;
		
		return 0;
	}

	private void outputEnergy() {
		
		if(energy.getEnergyStored() > 0)
		{
			for(Direction direction : Direction.values())
			{
				if(world.getTileEntity(pos.offset(direction)) != null)
				{
					TileEntity tileEntity = world.getTileEntity(pos.offset(direction));
					if(tileEntity.getCapability(CapabilityEnergy.ENERGY, direction.getOpposite()) != null)
					{
						IEnergyStorage storage = (IEnergyStorage) tileEntity.getCapability(CapabilityEnergy.ENERGY, direction.getOpposite());
						if(storage.getEnergyStored() < storage.getMaxEnergyStored())
						{
							int accepted = energy.extractEnergy(10, false);
							storage.receiveEnergy(accepted, false);
							//let vanilla update chunk
							this.markDirty();	
							//Notify client of a block update
							//This will result in the packet from getUpdatePacket beong sent to the client
							//Energy will be synced
							//Flag 2 send change to client
							world.notifyBlockUpdate(pos, this.getBlockState(), this.getBlockState(), 2);
							//Update the last energy to the current
							lastEnergy = energy.getEnergyStored();
						}
					}
				}
			}
		}
	}
	
	@Override
	public <T> LazyOptional<T> getCapability(@Nullable final Capability<T> cap, @Nullable final Direction side) {

		if(cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
		{
			if(side == null)
				return inventoryCapabilities.cast();
			else if(side != Direction.DOWN)
				return InventorycapabilitiesUpAndSides.cast();
			else 
				return InventoryCapabilitiesDown.cast();
		}
		
		if(cap == CapabilityEnergy.ENERGY)
			return energyCapabilitiesExternal.cast();
		
		return super.getCapability(cap, side);
	}
	
	/*
	 * Handle a packet created in (@link #getUpdatePacket())
	 */
	@Override
	public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {

		this.energy.setEnergy(pkt.getNbtCompound().getInt(ENERGY_TAG));
	}
	
	
	@Override
	public void onLoad() {
		
		super.onLoad();
		//Set this in onLoad instead of the constructor so that TileEntities constructed from NBT(saved tile entities) have this set to the proper value
		if(world != null && !world.isRemote)
			this.lastEnergy = this.energy.getEnergyStored();
	}
	
	
	/*
	 * 	Read saved data from disk into the tile entity
	 */
	@Override
	public void read(CompoundNBT compound) {

		super.read(compound);
		this.inventory.deserializeNBT(compound.getCompound(INVENTORY_TAG));
		this.smeltTimeLeft = compound.getShort(SMELT_TIME_LEFT_TAG);
		this.maxSmeltTime = compound.getShort(MAX_SMELT_TIME_TAG);
		this.energy.setEnergy(compound.getInt(ENERGY_TAG));
	}
	
	
	/*
	 * 	Write data from tile entity into a compound for saving to disk
	 */
	@Nonnull
	@Override
	public CompoundNBT write(CompoundNBT compound) {

		super.write(compound);
		compound.put(INVENTORY_TAG, this.inventory.serializeNBT());
		compound.putInt(ENERGY_TAG, this.energy.getEnergyStored());
		compound.putShort(MAX_SMELT_TIME_TAG, this.maxSmeltTime);
		compound.putShort(SMELT_TIME_LEFT_TAG, smeltTimeLeft);
		
		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(ENERGY_TAG, this.energy.getEnergyStored());
		//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());
	}
	
	
	/*
	 * Invalidates our Tile Entity 
	 */
	@Override
	public void remove() {

		super.remove();
		//We need to invalidate our capability references so that any cached references (by other mod) don't continue to reference our capablities
		//and try to use them and/or prevent them from being garbage collected
		inventoryCapabilities.invalidate();
		energyCapabilitiesExternal.invalidate();
	}
	
	@Nonnull
	@Override
	public Container createMenu(final int windowID, final PlayerInventory playerInventory, final PlayerEntity player) {

		return new GlowStoneGeneratorContainer(windowID, playerInventory, this);
	}

	@Override
	public ITextComponent getDisplayName() {

		return new TranslationTextComponent(BlockInit.GLOWSTONE_GENERATOR.getTranslationKey());
	}

}

 

Container

package com.olivemod.energy.generator.glowstone_generator;

import java.util.Objects;

import javax.annotation.Nonnull;

import com.olivemod.init.BlockInit;
import com.olivemod.utils.FunctionalIntReferenceHolder;
import com.olivemod.utils.ModContainerTypes;

import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IWorldPosCallable;
import net.minecraftforge.items.SlotItemHandler;


/*
 * Smelt time is synced with:
 * Server: each tick {@link #detectAndSendChanges()} is called ({@link ServerPlayerEntity#tick()})
 * 
 * Server: The (tracked) value of the tile's energy is updated ({@link #updateprogressBar(int, int)})
 * 
 * Server: if the value is different from the value last sent to the client ({@link IntReferenceHolder#isDirty()}), 
 * it is synced to the client ({@link ServerPlayerEntity#senWindowProperty(Container, int, int)})
 * 
 * Client: the sync packet is received ({@link ClientPlayNetHandler#handleWindowProperty(SWindowPropertyPacket)})
 * and the tracked value of is updated ({@link Container#updateProgressBar(int, int)})
 * 
 * Client: the tile's data is updated to the new value
 */

public class GlowStoneGeneratorContainer extends Container {

	public final TileEntityGlowStoneGenerator tileEntity;
	private final IWorldPosCallable canInteractWithCallable;
	
	public GlowStoneGeneratorContainer(int windowID, PlayerInventory playerInventory, final PacketBuffer data) {
		
		this(windowID, playerInventory, getTileEntity(playerInventory, data));
	}
	
	public GlowStoneGeneratorContainer(int windowID, PlayerInventory playerInventory, TileEntityGlowStoneGenerator tileEntity) {
		
		super(ModContainerTypes.GLOWSTONE_GENERATOR_CONTAINER, windowID);
		this.tileEntity = tileEntity;
		this.canInteractWithCallable = IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos());
		//Add tracking for data (Syncs client/updates value when it changes)
		this.trackInt(new FunctionalIntReferenceHolder( () -> tileEntity.smeltTimeLeft, v -> tileEntity.smeltTimeLeft = (short) v));
		this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.maxSmeltTime, v -> tileEntity.maxSmeltTime = (short) v));
		
		//Add all machine's tile entity's slot and player's
		
		//Machine
		this.addSlot(new SlotItemHandler(tileEntity.inventory, TileEntityGlowStoneGenerator.INPUT_SLOT, 44, 12));
		this.addSlot(new SlotItemHandler(tileEntity.inventory, TileEntityGlowStoneGenerator.OUTPUT_SLOT, 132, 163));
		
		final int playerInventoryStartX = 8;
		final int playerInventoryStartY = 84;
		final int sizeSlot = 18; 	//slot is 16*16, but we take care of 2px of spacing/border
		
		//Player's top inventory
		for(int x = 1; x < 4; x++)
		{
			for(int y = 1; y < 10; y++)
			{
				this.addSlot(new Slot(playerInventory, 9 + (x*9) + y, playerInventoryStartX + (y*sizeSlot), playerInventoryStartY + (x*sizeSlot)));
			}
		}
		
		final int playerHotbarY = playerInventoryStartY + sizeSlot*3 + 4;
		for(int i = 1; i < 10; i++)
		{
			this.addSlot(new Slot(playerInventory, i, playerInventoryStartX + (i*sizeSlot), playerHotbarY));
		}
	}
	
	private static TileEntityGlowStoneGenerator getTileEntity(final PlayerInventory playerInventory, final PacketBuffer data) {
		
		Objects.requireNonNull(playerInventory, "Player Inventory can not be null");
		Objects.requireNonNull(data, "Data can not be null");
		final TileEntity tileEntity = playerInventory.player.world.getTileEntity(data.readBlockPos());
		if(tileEntity instanceof TileEntityGlowStoneGenerator)
			return (TileEntityGlowStoneGenerator) tileEntity;
		throw new IllegalStateException("Tile Entity invalid at" + tileEntity);
	}
	
	@Nonnull
	@Override
	public ItemStack transferStackInSlot(final PlayerEntity player, final int index) {
		ItemStack returnStack = ItemStack.EMPTY;
		final Slot slot = this.inventorySlots.get(index);
		if (slot != null && slot.getHasStack()) 
		{
			final ItemStack slotStack = slot.getStack();
			returnStack = slotStack.copy();

			final int containerSlots = this.inventorySlots.size() - player.inventory.mainInventory.size();
			if (index < containerSlots) 
			{
				if (!mergeItemStack(slotStack, containerSlots, this.inventorySlots.size(), true)) 
				{
					return ItemStack.EMPTY;
				}
			} 
			else if (!mergeItemStack(slotStack, 0, containerSlots, false)) 
			{
				return ItemStack.EMPTY;
			}
			
			if (slotStack.getCount() == 0) 
			{
				slot.putStack(ItemStack.EMPTY);
			} 
			else 
			{
				slot.onSlotChanged();
			}
			if (slotStack.getCount() == returnStack.getCount()) 
			{
				return ItemStack.EMPTY;
			}
			slot.onTake(player, slotStack);
		}
		return returnStack;
	}

	@Override
	public boolean canInteractWith(PlayerEntity playerIn) {

		return isWithinUsableDistance(canInteractWithCallable, playerIn, BlockInit.GLOWSTONE_GENERATOR);
	}

}

 

Screen

package com.olivemod.energy.generator.glowstone_generator;

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

import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.energy.EnergyStorage;

public class GlowStoneGeneratorScreen extends ContainerScreen<GlowStoneGeneratorContainer>{
	
	private final ResourceLocation guiLocation = new ResourceLocation(Reference.MOD_ID, "textures/gui/generators/glowstone_generator_gui");

	public GlowStoneGeneratorScreen(GlowStoneGeneratorContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
		super(screenContainer, inv, titleIn);
		
	}
	
	@Override
	public void render(final int mouseX, final int mouseY, final float partialTick) {
		
		this.renderBackground();
		super.render(mouseX, mouseY, partialTick);
		this.renderHoveredToolTip(mouseX, mouseY);
		
		int relMouseX = mouseX - this.guiLeft;
		int relMouseY = mouseY - this.guiTop;
		
		final TileEntityGlowStoneGenerator tileEntityGlowStoneGenerator = this.container.tileEntity;
		boolean energyBarHovered = relMouseX > 150 && relMouseX < 170 && relMouseY > 4 && relMouseY < 81;
		if(energyBarHovered)
		{
			String toolTip = new TranslationTextComponent("gui." + Reference.MOD_ID + ".energy", tileEntityGlowStoneGenerator.energy.getEnergyStored()).getFormattedText();
			this.renderTooltip(toolTip, mouseX, mouseY);
		}
	}
	
	@Override
	protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
		
		super.drawGuiContainerForegroundLayer(mouseX, mouseY);
		String string = this.title.getFormattedText();
		this.font.drawString(string, (float)(this.xSize / 2 - this.font.getStringWidth(string) / 2), 6.0F, 0x404040);
		this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (this.ySize - 96 + 2), 0x404040);
	}

	@Override
	protected void drawGuiContainerBackgroundLayer(final float partialTicks, final int mouseX, final int mouseY) {
		
		GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
		getMinecraft().getTextureManager().bindTexture(guiLocation);
		
		int startX = this.guiLeft;
		int startY = this.guiTop;
		
		// Screen #blit draws a part of the current texture (assumed to be 256x256) to the screen
		// The parameters are (x, y, u, v, width, height)		
		this.blit(startX, startY, 0, 0, this.xSize, this.ySize);
		
		final TileEntityGlowStoneGenerator tileEntityGlowStoneGenerator = container.tileEntity;
		if(tileEntityGlowStoneGenerator.energy.getEnergyStored() > 0)
		{
			this.blit(startX + 150, startY + 4 + 80 - getEnergyProgressScaled(), 177, 18, 17, 91 - getEnergyProgressScaled());
		}
		if(tileEntityGlowStoneGenerator.smeltTimeLeft > 0)
			this.blit(startX + 68, startY + 30, 177, 0, 24 - getCookProgressScaled(), 17);
	}

	final TileEntityGlowStoneGenerator tileEntityGlowStoneGenerator = container.tileEntity;
	
	private int getCookProgressScaled() {
		
		if(tileEntityGlowStoneGenerator.maxSmeltTime <= 0 || tileEntityGlowStoneGenerator.smeltTimeLeft <= 0)
			return 0;
		
		return Math.round((float)tileEntityGlowStoneGenerator.smeltTimeLeft / (float)tileEntityGlowStoneGenerator.maxSmeltTime * 22);
	}

	private int getEnergyProgressScaled() {

		final EnergyStorage storage = tileEntityGlowStoneGenerator.energy;
		return Math.round((float)storage.getEnergyStored() / (float)storage.getMaxEnergyStored() * 74);
	}

}

 

TileEntityRender

package com.olivemod.energy.generator.glowstone_generator;

import com.mojang.blaze3d.platform.GlStateManager;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.item.ItemStack;

public class TileEntityGlowStoneGeneratorRenderer extends TileEntityRenderer<TileEntityGlowStoneGenerator> {

	/**
	 * Render our TileEntity
	 */
	@Override
	public void render(final TileEntityGlowStoneGenerator tileEntityIn, final double x, final double y, final double z, final float partialTicks, final int destroyStage) {
		super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);

		// Set up GL state
		RenderHelper.enableStandardItemLighting();

		GlStateManager.pushMatrix();

		// Translate to render pos. The 0.5 is to translate into the centre of the block, rather than to the corner of it
		GlStateManager.translated(x + 0.5, y, z + 0.5);

		// Translate to the place the item should be rendered (1/16 = the size of 1 pixel in the model)
		GlStateManager.translated(0, 1 / 16D, 0);

		// Render the item
		final ItemStack stackInInputSlot = tileEntityIn.inventory.getStackInSlot(TileEntityGlowStoneGenerator.INPUT_SLOT);
		Minecraft.getInstance().getItemRenderer().renderItem(stackInInputSlot, TransformType.FIXED);

		GlStateManager.popMatrix();

		// Clean up GL state
		RenderHelper.disableStandardItemLighting();
	}
}

 

Posted (edited)

I understood what you said about the block instance in constructor, but I don't understand  "construct an instance". I am learning.

 

So I should follow step by step Cadiboo's guide? I mean inside the class. I shouldn't register in that way.

 

Edited by dyno
Posted (edited)

I'm learning java in this period. I've been programming for 2 years, but just since January with OOP. I know to have a lot to learn about.

Anyway,I have an error when I right click:

Description: Unexpected error

java.lang.NullPointerException: Unexpected error
	at com.olivemod.energy.generator.glowstone_generator.GlowStoneGenerator.createTileEntity(GlowStoneGenerator.java:178) ~[main/:?] {re:classloading}
	at net.minecraftforge.common.extensions.IForgeBlockState.createTileEntity(IForgeBlockState.java:149) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.world.chunk.Chunk.setBlockState(Chunk.java:291) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.world.World.setBlockState(World.java:214) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.item.BlockItem.placeBlock(BlockItem.java:149) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.item.BlockItem.tryPlace(BlockItem.java:57) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.item.BlockItem.onItemUse(BlockItem.java:42) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.item.ItemStack.lambda$onItemUse$0(ItemStack.java:169) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:184) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:169) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading}
	at net.minecraft.client.multiplayer.PlayerController.func_217292_a(PlayerController.java:310) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1286) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:1544) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.runTick(Minecraft.java:1377) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:904) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.Minecraft.run(Minecraft.java:384) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A}
	at net.minecraft.client.main.Main.main(Main.java:128) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A}
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_231] {}
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_231] {}
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_231] {}
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_231] {}
	at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:55) ~[forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-4.1.0.jar:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-4.1.0.jar:?] {}
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-4.1.0.jar:?] {}
	at cpw.mods.modlauncher.Launcher.run(Launcher.java:81) [modlauncher-4.1.0.jar:?] {}
	at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-4.1.0.jar:?] {}
	at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:102) [forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {}

 

I tried with "return new TileEntity...()" in createTileEntity() and game crushes:

---- Minecraft Crash Report ----
// Why did you do that?

Time: 15/05/20 19.22
Description: Ticking block entity

java.lang.NullPointerException: Ticking block entity
	at net.minecraft.world.World.func_217391_K(World.java:670) ~[?:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.world.server.ServerWorld.tick(ServerWorld.java:370) ~[?:?] {re:classloading}
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:867) ~[?:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:802) ~[?:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) ~[?:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:648) [?:?] {re:classloading,pl:accesstransformer:B}
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_231] {}


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread
Stacktrace:
	at net.minecraft.world.World.func_217391_K(World.java:670)

-- Block entity being ticked --
Details:
	Name: null // com.olivemod.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator
	Block: Block{olivemod:glowstone_generator}[facing=north]
	Block location: World: (89,4,-36), Chunk: (at 9,0,12 in 5,-3; contains blocks 80,0,-48 to 95,255,-33), Region: (0,-1; contains chunks 0,-32 to 31,-1, blocks 0,0,-512 to 511,255,-1)
	Block: Block{olivemod:glowstone_generator}[facing=north]
	Block location: World: (89,4,-36), Chunk: (at 9,0,12 in 5,-3; contains blocks 80,0,-48 to 95,255,-33), Region: (0,-1; contains chunks 0,-32 to 31,-1, blocks 0,0,-512 to 511,255,-1)
Stacktrace:
	at net.minecraft.world.World.func_217391_K(World.java:670)
	at net.minecraft.world.server.ServerWorld.tick(ServerWorld.java:370)

-- Affected level --
Details:
	All players: 1 total; [ServerPlayerEntity['Dev'/199, l='New World', x=89.50, y=4.00, z=-37.50]]
	Chunk stats: ServerChunkCache: 2025
	Level dimension: DimensionType{minecraft:overworld}
	Level name: New World
	Level seed: -8990482801704672408
	Level generator: ID 01 - flat, ver 0. Features enabled: true
	Level generator options: {}
	Level spawn location: World: (80,4,-32), Chunk: (at 0,0,0 in 5,-2; contains blocks 80,0,-32 to 95,255,-17), Region: (0,-1; contains chunks 0,-32 to 31,-1, blocks 0,0,-512 to 511,255,-1)
	Level time: 1135 game time, 1135 day time
	Level storage version: 0x04ABD - Anvil
	Level weather: Rain time: 178155 (now: false), thunder time: 92761 (now: false)
	Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true
Stacktrace:
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:867)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:802)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:648)
	at java.lang.Thread.run(Thread.java:748)

-- System Details --
Details:
	Minecraft Version: 1.14.4
	Minecraft Version ID: 1.14.4
	Operating System: Windows 10 (amd64) version 10.0
	Java Version: 1.8.0_231, Oracle Corporation
	Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
	Memory: 691595152 bytes (659 MB) / 3164602368 bytes (3018 MB) up to 7635730432 bytes (7282 MB)
	CPUs: 4
	JVM Flags: 2 total; -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx8G
	ModLauncher: 4.1.0+62+5bfa59b
	ModLauncher launch target: fmluserdevclient
	ModLauncher naming: mcp
	ModLauncher services: 
		/eventbus-1.0.0-service.jar eventbus PLUGINSERVICE 
		/forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-launcher.jar object_holder_definalize PLUGINSERVICE 
		/forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-launcher.jar runtime_enum_extender PLUGINSERVICE 
		/accesstransformers-1.0.5-shadowed.jar accesstransformer PLUGINSERVICE 
		/forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-launcher.jar capability_inject_definalize PLUGINSERVICE 
		/forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-launcher.jar runtimedistcleaner PLUGINSERVICE 
		/forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-launcher.jar fml TRANSFORMATIONSERVICE 
	FML: 28.2
	Forge: net.minecraftforge:28.2.10
	FML Language Providers: 
		[email protected]
		minecraft@1
	Mod List: 
		client-extra.jar Minecraft {[email protected] DONE}
		forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar Forge {[email protected] DONE}
		main Example Mod {olivemod@NONE DONE}
	Player Count: 1 / 8; [ServerPlayerEntity['Dev'/199, l='New World', x=89.50, y=4.00, z=-37.50]]
	Data Packs: vanilla, mod:forge, mod:olivemod
	Type: Integrated Server (map_client.txt)
	Is Modded: Definitely; Client brand changed to 'forge'

 

Edited by dyno

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.