Jump to content

LazyOptional crushes casting to IEnergyStorage


dyno

Recommended Posts

When Generator's charge slot contains a battery, crush

SettableEnergyStorage:

package com.olivemod.energy.SeattableEnergyStorage;

import net.minecraftforge.energy.EnergyStorage;

public class SettableEnergyStorage extends EnergyStorage{

	public SettableEnergyStorage(final int capacity) {
		super(capacity);
		// TODO Auto-generated constructor stub
	}
	
	public SettableEnergyStorage(final int capacity, final int maxTransfer) {
		super(capacity, maxTransfer);
		// TODO Auto-generated constructor stub
	}
	
	public SettableEnergyStorage(final int capacity, final int maxReceive, final int maxExtract) {
		super(capacity, maxReceive, maxExtract);
		// TODO Auto-generated constructor stub
	}
	
	public SettableEnergyStorage(final int capacity, final int maxReceive, final int maxExtract, final int energy) {
		super(capacity, maxReceive, maxExtract, energy);
		// TODO Auto-generated constructor stub
	}
	
	//@Return the amount of energy was put into the storage
	@SuppressWarnings("unused")
	public int setEnergy(final int maxSet) {

		return this.energy = Math.min(this.capacity, maxSet);
	}
	


}

TEGenerator:

package com.olivemod.blocks.machine.energy.generator.glowstone_generator;

import javax.annotation.Nonnull;

import com.olivemod.energy.SeattableEnergyStorage.CapabilityProviderEnergy;
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.tileentity.TileEntityType;
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_TE.get()); 
	}
	
	public TileEntityGlowStoneGenerator(TileEntityType<?> typeIn) {
		super(typeIn);
	}

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

	private void charge() {
		ItemStack itemStack = this.inventory.getStackInSlot(1);
		if(!itemStack.isEmpty())
		{
			if(this.energy.getEnergyStored() > 0)
			{
				IEnergyStorage storageToCharge = (IEnergyStorage) itemStack.getCapability(CapabilityEnergy.ENERGY);
				
				if(storageToCharge != null && storageToCharge.getEnergyStored() < storageToCharge.getMaxEnergyStored())
				{
					
					int accepted = storageToCharge.receiveEnergy(10, false);
					this.energy.receiveEnergy(this.energy.getEnergyStored() - 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();
				}
			}
		}
		
	}

	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);
					this.energy.setEnergy(this.energy.getEnergyStored() + getEnergyFromItem(input));
					//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.get().getTranslationKey());
	}

}

Battery

package com.olivemod.items.battery;

import com.olivemod.energy.SeattableEnergyStorage.CapabilityProviderEnergy;
import com.olivemod.energy.SeattableEnergyStorage.SettableEnergyStorage;
import com.olivemod.utils.Reference.Reference;

import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.EnergyStorage;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;

public class Battery extends Item implements ICapabilitySerializable<CompoundNBT>{

	private SettableEnergyStorage storage = new SettableEnergyStorage(2500, 100, 100);	
	private final LazyOptional<EnergyStorage> energyCapabilitiesExternal = LazyOptional.of(() -> this.storage);
	private final ItemStack itemStack;
	
	public Battery(Properties properties) {
		super(properties);
		this.itemStack = new ItemStack(this);
	}
	
	@SubscribeEvent
	public void onAttachCapabilities(AttachCapabilitiesEvent<ItemStack> event){
		if(event.getObject().hasTag())
		{
			if(event.getObject().getTag().contains("Energy"))
			{
				event.addCapability(new ResourceLocation(Reference.MOD_ID + "battery"), new ICapabilityProvider() {
					
					@Override
					public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {

						if(cap == CapabilityEnergy.ENERGY)
							return energyCapabilitiesExternal.cast();
						
						return null;
					}
				} );
			}
		}
		else 
		{
			event.getObject().setTag(new CompoundNBT());
		}
	}
	

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

		if(cap == CapabilityEnergy.ENERGY)
			return energyCapabilitiesExternal.cast();
		
		return null;
	}

	@Override
	public CompoundNBT serializeNBT() {

		if(!itemStack.hasTag())
			itemStack.setTag(new CompoundNBT());
		
		CompoundNBT nbt = itemStack.getTag();
		assert nbt != null;
		nbt.putInt("Energy", this.storage.getEnergyStored());
		
		return nbt;
	}

	@Override
	public void deserializeNBT(CompoundNBT nbt) {
		
		if(itemStack.hasTag())
			this.storage.setEnergy(nbt.getInt("Energy"));
	}

}

Console:

---- Minecraft Crash Report ----
// There are four lights!

Time: 19/05/20 9.35
Description: Ticking block entity

java.lang.ClassCastException: net.minecraftforge.common.util.LazyOptional cannot be cast to net.minecraftforge.energy.IEnergyStorage
	at com.olivemod.blocks.machine.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator.charge(TileEntityGlowStoneGenerator.java:111) ~[?:?] {re:classloading}
	at com.olivemod.blocks.machine.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator.tick(TileEntityGlowStoneGenerator.java:102) ~[?:?] {re:classloading}
	at net.minecraft.world.World.func_217391_K(World.java:671) ~[?:?] {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 com.olivemod.blocks.machine.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator.charge(TileEntityGlowStoneGenerator.java:111)
	at com.olivemod.blocks.machine.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator.tick(TileEntityGlowStoneGenerator.java:102)

-- Block entity being ticked --
Details:
	Name: olivemod:glowstone_generator // com.olivemod.blocks.machine.energy.generator.glowstone_generator.TileEntityGlowStoneGenerator
	Block: Block{olivemod:glowstone_generator}[facing=north]
	Block location: World: (127,4,-196), Chunk: (at 15,0,12 in 7,-13; contains blocks 112,0,-208 to 127,255,-193), 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: (127,4,-196), Chunk: (at 15,0,12 in 7,-13; contains blocks 112,0,-208 to 127,255,-193), 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:671)
	at net.minecraft.world.server.ServerWorld.tick(ServerWorld.java:370)

-- Affected level --
Details:
	All players: 0 total; []
	Chunk stats: ServerChunkCache: 2025
	Level dimension: DimensionType{minecraft:overworld}
	Level name: New World
	Level seed: 7690030581214142000
	Level generator: ID 01 - flat, ver 0. Features enabled: true
	Level generator options: {}
	Level spawn location: World: (128,4,-192), Chunk: (at 0,0,0 in 8,-12; contains blocks 128,0,-192 to 143,255,-177), Region: (0,-1; contains chunks 0,-32 to 31,-1, blocks 0,0,-512 to 511,255,-1)
	Level time: 941 game time, 941 day time
	Level storage version: 0x04ABD - Anvil
	Level weather: Rain time: 113334 (now: false), thunder time: 79221 (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: 2652407688 bytes (2529 MB) / 3642753024 bytes (3474 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: 
		javafml@28.2
		minecraft@1
	Mod List: 
		client-extra.jar Minecraft {minecraft@1.14.4 DONE}
		forge-1.14.4-28.2.10_mapped_snapshot_20190719-1.14.3-recomp.jar Forge {forge@28.2.10 DONE}
		main Example Mod {olivemod@NONE DONE}
	Player Count: 0 / 8; []
	Data Packs: vanilla, mod:forge, mod:olivemod
	Type: Integrated Server (map_client.txt)
	Is Modded: Definitely; Client brand changed to 'forge'

 

Sorry for all topics I am creating in these days, I was learning in 1.12.2 and switch to 1.14.4 seems a nightmare.

If someone could give me some gitHub'projects to learn from, too, would be great.

Link to comment
Share on other sites

LazyOptional's are wrappers for a supplier that may or may not be stored at that time.

With LazyOptional's you gotta check the type for whether it has a supplier or not by checking isPresent() on it, then use getValue(). You could also just skip the check and use getValue() but you'd have to then check to see if the returned value is null. So basically anywhere you are using a LazyOptional you have to use the getValue() method on it if you actually want the value.

EDIT: yeah ignore this I messed up reading the LazyOptional methods last night and didn't notice getValue() was a private method and that it forces you to supply a consumer to ifPresent.

Edited by AtlaStar
Made a dumb dumb when tired
Link to comment
Share on other sites

1 hour ago, AtlaStar said:

LazyOptional's are wrappers for a supplier that may or may not be stored at that time.

With LazyOptional's you gotta check the type for whether it has a supplier or not by checking isPresent() on it, then use getValue(). You could also just skip the check and use getValue() but you'd have to then check to see if the returned value is null. So basically anywhere you are using a LazyOptional you have to use the getValue() method on it if you actually want the value.

Could you give me link some project on gitHub, just to understand better?

Thanks

Link to comment
Share on other sites

3 hours ago, AtlaStar said:

LazyOptional's are wrappers for a supplier that may or may not be stored at that time.

With LazyOptional's you gotta check the type for whether it has a supplier or not by checking isPresent() on it, then use getValue(). You could also just skip the check and use getValue() but you'd have to then check to see if the returned value is null. So basically anywhere you are using a LazyOptional you have to use the getValue() method on it if you actually want the value.

?? that is all false

 

if you dont know if it has a cap use for interfacing w/ other tileEntitys

energyCapabilitiesExternal.ifPesent(lambda goes here)

 

if you know if you have a cap there use

energyCapabilitiesExternal.orElsethrow(throw a runtimeexception there)

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, loordgek said:

?? that is all false

 

if you dont know if it has a cap use for interfacing w/ other tileEntitys

energyCapabilitiesExternal.ifPesent(lambda goes here)

 

if you know if you have a cap there use

energyCapabilitiesExternal.orElsethrow(throw a runtimeexception there)

 

Please, you all are getting me confused. 

I just wanna make an item with Energy Capability(and lears something new), and the glowstone generatore should charge It.

But please, I am new in modding, so try to don't get confused me.

 

To make that item, what I should do? Last topic that said to attach AttachingCapabilitiesEvent, but I cannot did it

And how I should check the Capability of item in the charge slot of Glowstone generator

 

And I say again, if someone could give me some project, It would be easier. So I won't annoy anybody more.

Anyway, thanks for support

Edited by dyno
Link to comment
Share on other sites

I'm not using the energy capability, but rather items, but the same features apply.

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/block/MillstoneBlock.java#L61

I'm also using orElse(null), but I wrote the code before figuring out ifPresent.

 

cap = getCap(CapType).orElse(null)
if(cap != null) {
    //code here
}

directly converts to

getCap(CapType).ifPresent(cap -> {
    //code here
}

 

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

dont use AttachingCapabilitiesEvent override initCapablilty in your item class.

 

7 hours ago, dyno said:

private SettableEnergyStorage storage = new SettableEnergyStorage(2500, 100, 100);

private final LazyOptional<EnergyStorage> energyCapabilitiesExternal = LazyOptional.of(() -> this.storage);

 

you cant do that because items are singeton

 

1 hour ago, dyno said:

if someone could give me some project

https://gist.github.com/e3986c6684e536940bba5494a51c13f2

Link to comment
Share on other sites

1 hour ago, loordgek said:

dont use AttachingCapabilitiesEvent override initCapablilty in your item class.

 

 

you cant do that because items are singeton

 

https://gist.github.com/e3986c6684e536940bba5494a51c13f2

 

Ok, thanks. What about charge() in TileEntityGlowstoneGenerator? I have still that crush. I have It on the cast from CapabilitEnergy.Energy to IEnergyStorage

 

How could I make to generator's TE get the Energy storage of the battery and charge It?

 

Link to comment
Share on other sites

19 minutes ago, loordgek said:

dont cast use


itemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent(storage -> {do your stuff here})

 

Sure a stupid question, whose storage is that?

Suppose battery's, how TE get It?

 

And how could it return the storage? Because then I should use IEnergyStorage#receiveEnergy()

 

Could you link a gitHub's project about something like? A generator

Edited by dyno
Link to comment
Share on other sites

1 hour ago, dyno said:

Sure a stupid question, whose storage is that?

It is the ENERGY capability attached to itemstack. As evidenced by the code, itemstack.getCapability(ENERGY) method call.

If that stack represents a battery, then its the battery.

1 hour ago, dyno said:

how TE get It?

Presumably your TE has item slots, using an ItemHandler capability, so your TE just needs to look into its inventory and go "hey, batteries!"

Your TE also has an energy storage capability it does the same thing, only on its own capability (there's no need to call getCapability inside your own TE, all that does is return a field the TE already has, wrapped in a LazyOptional, so you may as well just access the field).

1 hour ago, dyno said:

And how could it return the storage?

You ... don't?

1 hour ago, dyno said:

Could you link a gitHub's project about something like? A generator

I don't know of any, but the process here is the same as it would be for items, just a different capability that returns a different data type. You call ifPresent, do some operations on that data, and it's automatically saved. Because that's what happens when you operate directly on the stored data.

 

ItemStackHandler is the ITEM capability equivalent to EVERGY's EnergyStorage.

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/entity/SifterTileEntity.java#L39

The lazy optional wrapper:

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/entity/SifterTileEntity.java#L42

Accessing the field data directly:

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/entity/SifterTileEntity.java#L109

The TE's getCapability, returning the wrapper
https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/entity/SifterTileEntity.java#L164-L166

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

8 hours ago, loordgek said:

?? that is all false

 

if you dont know if it has a cap use for interfacing w/ other tileEntitys

energyCapabilitiesExternal.ifPesent(lambda goes here)

 

if you know if you have a cap there use

energyCapabilitiesExternal.orElsethrow(throw a runtimeexception there)

 

I was dead tired looking at the LasyOptional type and didn't notice getValue was a private member and that the class forces you to pass a consumer, so my mistake.

Link to comment
Share on other sites

If you really want to return something obtained from the value of a LazyOptional, you could use LazyOptional#orElse.

 

Note that in 99% of the cases you could just use ifPresent and do what you want in there.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

2 hours ago, DavidM said:

If you really want to return something obtained from the value of a LazyOptional, you could use LazyOptional#orElse.

 

Note that in 99% of the cases you could just use ifPresent and do what you want in there.

My problem Is that I wanna charge item when Is in the slot, but I didn't understand how because I am new in 1.14.4(before I made in 1.12.2), and it was easier.

 

What I would do is this:

IEnergyStorage storage = itemstack.getCapability(CapabilityEnergy.ENERGY), how did in 1.12.2.

I should write ifPresent, but I don't understand what write at ifPresent(energy -> ...).

I should call method to charge battery, but how if I don't get the its storage.

I tried (energy -> enegy.receiveEnergy()) but of course battery doesn't charge because It Is the generator's storage

 

Link to comment
Share on other sites

23 hours ago, Draco18s said:

This


cap = getCap(CapType).orElse(null)
if(cap != null) {
    //code here
}

directly converts to


getCap(CapType).ifPresent(cap -> {
    //code here
}

 

 

  • Haha 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

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.