AbstractEngineTileEntity:
public abstract class AbstractEngineTileEntity extends TileEntity implements ITickableTileEntity {
protected int counter;
protected CustomEnergyStorage energyStorage = createEnergy();
protected LazyOptional<IEnergyStorage> energy = LazyOptional.of(() -> energyStorage);
public AbstractEngineTileEntity(TileEntityType type) {
super(type);
}
private CustomEnergyStorage createEnergy() {
return new CustomEnergyStorage(Config.COMBUSTION_ENGINE_MAX_POWER, 0) {
@Override
protected void onEnergyChanged() {
setChanged();
}
};
}
@Override
public void load(BlockState state, CompoundNBT tag) {
super.load(state, tag);
}
@Override
public CompoundNBT save(CompoundNBT tag) {
return super.save(tag);
}
@Override
public CompoundNBT getUpdateTag() {
return this.save(new CompoundNBT());
}
@Override
public SUpdateTileEntityPacket getUpdatePacket() {
CompoundNBT nbt = new CompoundNBT();
this.save(nbt);
return new SUpdateTileEntityPacket(this.getBlockPos(), 0, nbt);
}
@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket packet) {
this.load(level.getBlockEntity(packet.getPos()).getBlockState(), packet.getTag());
}
@Override
public abstract void tick();
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
if (cap == CapabilityEnergy.ENERGY) {
return energy.cast();
} return super.getCapability(cap, side);
}
}
CombustionEngineTileEntity:
public class CombustionEngineTileEntity extends AbstractEngineTileEntity {
protected ItemStackHandler itemHandler = createHandler();
protected LazyOptional<IItemHandler> handler = LazyOptional.of(() -> itemHandler);
public CombustionEngineTileEntity() {
super(Registration.COMBUSTION_ENGINE_TILE_ENTITY.get());
}
@Override
public void setRemoved() {
super.setRemoved();
handler.invalidate();
energy.invalidate();
}
@Override
public void tick() {
if (level.isClientSide) {
return;
}
if (counter > 0) {
counter--;
if (counter <= 0) {
energyStorage.addEnergy(Config.COMBUSTION_ENGINE_GENERATION);
} setChanged();
}
if (counter <= 0) {
ItemStack stack = itemHandler.getStackInSlot(0);
if (stack.getItem() == Items.DIAMOND) {
itemHandler.extractItem(0, 1, false);
counter = Config.COMBUSTION_ENGINE_TICKS;
setChanged();
}
}
BlockState blockState = level.getBlockState(getBlockPos());
if (blockState.getValue(BlockStateProperties.POWERED) != counter > 0) {
level.setBlock(getBlockPos(), blockState.setValue(BlockStateProperties.POWERED, counter > 0),
Constants.BlockFlags.NOTIFY_NEIGHBORS + Constants.BlockFlags.BLOCK_UPDATE);
} sendOutPower();
}
private void sendOutPower() {
AtomicInteger capacity = new AtomicInteger(energyStorage.getEnergyStored());
if (capacity.get() > 0) {
for (Direction direction : Direction.values()) {
TileEntity te = level.getBlockEntity(getBlockPos().offset(new Vector3i(direction.getStepX(), direction.getStepY(), direction.getStepZ())));
if (te != null) {
boolean doContinue = te.getCapability(CapabilityEnergy.ENERGY, direction).map(energy -> {
if (energy.canReceive()) {
int received = energy.receiveEnergy(Math.min(capacity.get(), Config.COMBUSTION_ENGINE_SEND), false);
capacity.addAndGet(-received);
energyStorage.consumeEnergy(received);
setChanged();
return capacity.get() > 0;
} else {
return true;
}
}).orElse(true);
if (!doContinue) {
return;
}
}
}
}
}
@Override
public void load(BlockState state, CompoundNBT tag) {
CompoundNBT inv = tag.getCompound("inv");
CompoundNBT item = inv.getCompound("item");
itemHandler.setStackInSlot(0, new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(item.getString("name"))), item.getInt("qty")));
energyStorage.setEnergy(tag.getInt("eng"));
counter = tag.getInt("counter");
super.load(state, tag);
}
@Override
public CompoundNBT save(CompoundNBT tag) {
CompoundNBT item = new CompoundNBT();
item.putString("name", itemHandler.getStackInSlot(0).getDisplayName().getString());
item.putInt("qty", itemHandler.getStackInSlot(0).getCount());
CompoundNBT inv = new CompoundNBT();
inv.put("item", item);
tag.put("inv", inv);
tag.putInt("eng", energyStorage.getEnergyStored());
tag.putInt("counter", counter);
return super.save(tag);
}
private ItemStackHandler createHandler() {
return new ItemStackHandler(1) {
@Override
protected void onContentsChanged(int slot) {
setChanged();
}
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
return stack.getItem() == Items.DIAMOND;
}
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (stack.getItem() != Items.DIAMOND) {
return stack;
} return super.insertItem(slot, stack, simulate);
}
};
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return handler.cast();
} return super.getCapability(cap, side);
}
}
Registration:
public class Registration {
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Noble.MOD_ID);
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Noble.MOD_ID);
public static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Noble.MOD_ID);
public static final DeferredRegister<TileEntityType<?>> TILE_ENTITIES = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, Noble.MOD_ID);
public static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, Noble.MOD_ID);
public static void init() {
BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
ENTITIES.register(FMLJavaModLoadingContext.get().getModEventBus());
TILE_ENTITIES.register(FMLJavaModLoadingContext.get().getModEventBus());
CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus());
}
public static final RegistryObject<CombustionEngineBlock> COMBUSTION_ENGINE_BLOCK = BLOCKS.register("combustion_engine", CombustionEngineBlock::new);
public static final RegistryObject<TileEntityType<CombustionEngineTileEntity>> COMBUSTION_ENGINE_TILE_ENTITY =
TILE_ENTITIES.register("combustion_engine", () -> TileEntityType.Builder.of(CombustionEngineTileEntity::new,
COMBUSTION_ENGINE_BLOCK.get()).build(null));
public static final RegistryObject<ContainerType<AbstractEngineContainer>> COMBUSTION_ENGINE_CONTAINER =
CONTAINERS.register("combustion_engine", () -> IForgeContainerType.create(CombustionEngineContainer::new));
}