Jump to content

NBT Writing / Reading issue.


Lambda

Recommended Posts

Hello all,

 

So I have these 'transreceivers' for transporting around energy, however, I'm having trouble saving the connections to NBT.

I do have a error that I caught, which is:

[21:58:54] [Client thread/FATAL]: Registering a TileEntity failed!
java.lang.InstantiationException: com.lambda.plentifulmisc.tile.TileEntityTransreceiverRelay
at java.lang.Class.newInstance(Class.java:427) ~[?:1.8.0_91]
at com.lambda.plentifulmisc.tile.TileEntityBase.register(TileEntityBase.java:66) [TileEntityBase.class:?]
at com.lambda.plentifulmisc.tile.TileEntityBase.init(TileEntityBase.java:57) [TileEntityBase.class:?]
at com.lambda.plentifulmisc.PlentifulMisc.init(PlentifulMisc.java:60) [PlentifulMisc.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:602) [FMLModContainer.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:243) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:221) [LoadController.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:145) [LoadController.class:?]
at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:795) [Loader.class:?]
at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:330) [FMLClientHandler.class:?]
at net.minecraft.client.Minecraft.startGame(Minecraft.java:560) [Minecraft.class:?]
at net.minecraft.client.Minecraft.run(Minecraft.java:385) [Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
at GradleStart.main(GradleStart.java:26) [start/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:?]
Caused by: java.lang.NoSuchMethodException: com.lambda.plentifulmisc.tile.TileEntityTransreceiverRelay.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[?:1.8.0_91]
at java.lang.Class.newInstance(Class.java:412) ~[?:1.8.0_91]
... 51 more

 

However, this error is from the 'base relay' which gets extended by the energy / fluid relays.

 

Here is the TE Base, where the TE are registered and just makes creating new TE easier:

 

ppackage com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/23/2016.
*/
import com.lambda.plentifulmisc.config.ConfigIntValues;
import com.lambda.plentifulmisc.network.PacketHandler;
import com.lambda.plentifulmisc.network.PacketServerToClient;
import com.lambda.plentifulmisc.util.ModUtil;
import com.lambda.plentifulmisc.util.StringUtil;
import com.lambda.plentifulmisc.util.WorldUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;

public abstract class TileEntityBase extends TileEntity implements ITickable{

    public final String name;
    public boolean isRedstonePowered;
    public boolean isPulseMode;
    protected int ticksElapsed;

    protected TileEntity[] tilesAround = new TileEntity[6];
    protected boolean hasSavedDataOnChangeOrWorldStart;

    public TileEntityBase(String name){
        this.name = name;
    }

    public static void init(){
        ModUtil.LOGGER.info("Registering TileEntities...");

        register(TileEntityCoalGenerator.class);
        register(TileEntityEnergeticFab.class);
        register(TileEntitySolarGenerator.class);
        register(TileEntityRefinery.class);
        register(TileEntityElectricFurnace.class);
        register(TileEntityCrusher.class);
        register(TileEntityAtomicDiffuser.class);
        register(TileEntityDigger.class);

        register(TileEntityTransreceiverRelay.class);
        register(TileEntityTransreceiverFluid.class);
        register(TileEntityTransreceiverRelayEnergyAdv.class);
        register(TileEntityTransreciverRelayEnergy.class);

    }

    private static void register(Class<? extends TileEntityBase> tileClass){
        try{
            String name = ModUtil.MOD_ID+":"+tileClass.newInstance().name;
            GameRegistry.registerTileEntity(tileClass, name);
        }
        catch(Exception e){
            ModUtil.LOGGER.fatal("Registering a TileEntity failed!", e);
        }
    }

    @Override
    public final NBTTagCompound writeToNBT(NBTTagCompound compound){
        this.writeSyncableNBT(compound, NBTType.SAVE_TILE);
        return compound;
    }

    @Override
    public final void readFromNBT(NBTTagCompound compound){
        this.readSyncableNBT(compound, NBTType.SAVE_TILE);
    }

    @Override
    public final SPacketUpdateTileEntity getUpdatePacket(){
        NBTTagCompound compound = new NBTTagCompound();
        this.writeSyncableNBT(compound, NBTType.SYNC);
        return new SPacketUpdateTileEntity(this.pos, -1, compound);
    }

    @Override
    public final void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt){
        this.readSyncableNBT(pkt.getNbtCompound(), NBTType.SYNC);
    }

    @Override
    public final NBTTagCompound getUpdateTag(){
        NBTTagCompound compound = new NBTTagCompound();
        this.writeSyncableNBT(compound, NBTType.SYNC);
        return compound;
    }

    @Override
    public final void handleUpdateTag(NBTTagCompound compound){
        this.readSyncableNBT(compound, NBTType.SYNC);
    }

    public final void sendUpdate(){
        if(!this.worldObj.isRemote){
            NBTTagCompound compound = new NBTTagCompound();
            this.writeSyncableNBT(compound, NBTType.SYNC);

            NBTTagCompound data = new NBTTagCompound();
            data.setTag("Data", compound);
            data.setInteger("X", this.pos.getX());
            data.setInteger("Y", this.pos.getY());
            data.setInteger("Z", this.pos.getZ());
            PacketHandler.theNetwork.sendToAllAround(new PacketServerToClient(data, PacketHandler.TILE_ENTITY_HANDLER), new NetworkRegistry.TargetPoint(this.worldObj.provider.getDimension(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), 128));
        }
    }

    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        if(type != NBTType.SAVE_BLOCK){
            super.writeToNBT(compound);
        }

        if(type == NBTType.SAVE_TILE){
            compound.setBoolean("Redstone", this.isRedstonePowered);
            compound.setInteger("TicksElapsed", this.ticksElapsed);
        }
    }

    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        if(type != NBTType.SAVE_BLOCK){
            super.readFromNBT(compound);
        }

        if(type == NBTType.SAVE_TILE){
            this.isRedstonePowered = compound.getBoolean("Redstone");
            this.ticksElapsed = compound.getInteger("TicksElapsed");
        }

    }

    @Override
    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState){
        return !oldState.getBlock().isAssociatedBlock(newState.getBlock());
    }

    public String getDisplayedName(){
        return StringUtil.localize("container."+ModUtil.MOD_ID+"."+this.name+".name");
    }

    @Override
    public ITextComponent getDisplayName(){
        return new TextComponentString(this.getDisplayedName());
    }

    @Override
    public final void update(){
         this.updateEntity();
    }

    public void updateEntity(){
        this.ticksElapsed++;

        if(!this.worldObj.isRemote && worldObj != null){
            if(this instanceof ISharingEnergyProvider){
                ISharingEnergyProvider provider = (ISharingEnergyProvider)this;
                if(provider.doesShareEnergy()){
                    int total = provider.getEnergyToSplitShare();
                    if(total > 0){
                        EnumFacing[] sides = provider.getEnergyShareSides();

                        int amount = total/sides.length;
                        if(amount <= 0){
                            amount = total;
                        }

                        for(EnumFacing side : sides){
                            TileEntity tile = this.tilesAround[side.ordinal()];
                            if(tile != null){
                                WorldUtil.doEnergyInteraction(this, tile, side, amount);
                            }
                        }
                    }
                }
            }

            if(this instanceof ISharingFluidHandler){
                ISharingFluidHandler handler = (ISharingFluidHandler)this;
                if(handler.doesShareFluid()){
                    int total = handler.getMaxFluidAmountToSplitShare();
                    if(total > 0){
                        EnumFacing[] sides = handler.getFluidShareSides();

                        int amount = total/sides.length;
                        if(amount <= 0){
                            amount = total;
                        }

                        for(EnumFacing side : sides){
                            TileEntity tile = this.tilesAround[side.ordinal()];
                            if(tile != null){
                                WorldUtil.doFluidInteraction(this, tile, side, amount);
                            }
                        }
                    }
                }
            }

            if(!this.hasSavedDataOnChangeOrWorldStart){
                if(this.shouldSaveDataOnChangeOrWorldStart()){
                    this.saveDataOnChangeOrWorldStart();
                }

                this.hasSavedDataOnChangeOrWorldStart = true;
            }
        }
    }

    public void saveDataOnChangeOrWorldStart(){
        for(EnumFacing side : EnumFacing.values()){
            this.tilesAround[side.ordinal()] = this.worldObj.getTileEntity(this.pos.offset(side));
        }
    }

    public boolean shouldSaveDataOnChangeOrWorldStart(){
        return this instanceof ISharingEnergyProvider || this instanceof ISharingFluidHandler;
    }

    public void setRedstonePowered(boolean powered){
        this.isRedstonePowered = powered;
        this.markDirty();
    }

    public boolean canPlayerUse(EntityPlayer player){
        return player.getDistanceSq(this.getPos().getX()+0.5D, this.pos.getY()+0.5D, this.pos.getZ()+0.5D) <= 64 && !this.isInvalid() && this.worldObj.getTileEntity(this.pos) == this;
    }

    protected boolean sendUpdateWithInterval(){
        if(this.ticksElapsed% 1 == 0){
            this.sendUpdate();
            return true;
        }
        else{
            return false;
        }

    }

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing){
        return this.getCapability(capability, facing) != null;
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing){
        if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
            IFluidHandler tank = this.getFluidHandler(facing);
            if (tank != null) {
                return (T) tank;
            }
        }
        return super.getCapability(capability, facing);
    }

    public IFluidHandler getFluidHandler(EnumFacing facing){
        return null;
    }

    public boolean isRedstoneToggle(){
        return false;
    }

    public void activateOnPulse(){

    }

    public enum NBTType{
        SAVE_TILE,
        SYNC,
        SAVE_BLOCK
    }
}

 

 

Now for the 'TileEntityTransreceiverRelay' , which gets extended by all other transrecievers:

 

 

 

package com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/25/2016.
*/
import com.lambda.api.transmitters.IConnectionPair;
import com.lambda.api.PlentifulMiscAPI;
import com.lambda.api.transmitters.TransreceiversType;
import com.lambda.plentifulmisc.util.misc.ConnectionPair;
import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.AxisAlignedBB;

import java.util.Set;

public abstract class TileEntityTransreceiverRelay extends TileEntityBase{

    public static final int MAX_DISTANCE = 15;

    public final TransreceiversType type;

    private Set<IConnectionPair> tempConnectionStorage;

    public TileEntityTransreceiverRelay(String name, TransreceiversType type){
        super(name);
        this.type = type;
    }



    @Override
    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        super.readSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);

            NBTTagList list = compound.getTagList("Connections", 10);
            if(!list.hasNoTags()){
                for(int i = 0; i < list.tagCount(); i++){
                    ConnectionPair pair = new ConnectionPair();
                    pair.readFromNBT(list.getCompoundTagAt(i));
                    PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], this.type, this.worldObj, pair.doesSuppressRender());
                }
            }
        }
    }

    @Override
    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        super.writeSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            NBTTagList list = new NBTTagList();

            ConcurrentSet<IConnectionPair> connections = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);
            if(connections != null && !connections.isEmpty()){
                for(IConnectionPair pair : connections){
                    NBTTagCompound tag = new NBTTagCompound();
                    pair.writeToNBT(tag);
                    list.appendTag(tag);
                }
            }

            compound.setTag("Connections", list);
        }
    }
/*
    @Override
    public void updateEntity(){
        super.updateEntity();
        if(this.worldObj.isRemote){
        }
    }

*/
    @Override
    public void invalidate(){
        super.invalidate();
        //This is because Minecraft randomly invalidates tiles on world join and then validates them again
        //We need to compensate for this so that connections don't get broken randomly
        this.tempConnectionStorage = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);

        PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);
    }

    @Override
    public void validate(){
        if(this.tempConnectionStorage != null){
            for(IConnectionPair pair : this.tempConnectionStorage){
                PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], pair.getType(), this.worldObj, pair.doesSuppressRender());
            }
            this.tempConnectionStorage = null;
        }

        super.validate();
    }

    @Override
    public AxisAlignedBB getRenderBoundingBox(){
        return INFINITE_EXTENT_AABB;
    }
}

 

 

 

Now for the 'TileEntityTransreceiverRelayEnergy', I'll just be using this one for example, all of them have the NBT issue, however. In this class, because the original Relay class was outputting an error, I overwrote the NBT READ/WRITE.

package com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/25/2016.
*/
import cofh.api.energy.IEnergyReceiver;
import com.lambda.api.transmitters.IConnectionPair;
import com.lambda.api.transmitters.Network;
import com.lambda.api.PlentifulMiscAPI;
import com.lambda.api.transmitters.TransreceiversType;
import com.lambda.plentifulmisc.config.ConfigBoolValues;
import com.lambda.plentifulmisc.util.misc.ConnectionPair;
import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TileEntityTransreciverRelayEnergy extends TileEntityTransreceiverRelay implements ICustomEnergyReceiver{

    public static final int CAP = 1000;
    public final ConcurrentHashMap<EnumFacing, TileEntity> receiversAround = new ConcurrentHashMap<EnumFacing, TileEntity>();

    public TileEntityTransreciverRelayEnergy(String name){
        super(name, TransreceiversType.ENERGY);
    }

    public TileEntityTransreciverRelayEnergy(){
        this("transreceiverRelay");
    }

    @Override
    public int receiveEnergy(EnumFacing from, int maxReceive, boolean simulate){
        return this.transmitEnergy(from, maxReceive, simulate);
    }

    @Override
    public int getEnergyStored(EnumFacing from){
        return 0;
    }

    @Override
    public int getMaxEnergyStored(EnumFacing from){
        return this.getEnergyCap();
    }

    private int transmitEnergy(EnumFacing from, int maxTransmit, boolean simulate){
        int transmitted = 0;
        if(maxTransmit > 0){
            Network network = PlentifulMiscAPI.connectionHandler.getNetworkFor(this.pos, this.worldObj);
            if(network != null){
                transmitted = this.transferEnergyToReceiverInNeed(from, network, maxTransmit, simulate);
            }
        }
        return transmitted;
    }

    @Override
    public boolean canConnectEnergy(EnumFacing from){
        return true;
    }

    @Override
    public boolean shouldSaveDataOnChangeOrWorldStart(){
        return true;
    }

    @Override
    public void saveDataOnChangeOrWorldStart(){
        Map<EnumFacing, TileEntity> old = new HashMap<EnumFacing, TileEntity>(this.receiversAround);
        boolean change = false;

        this.receiversAround.clear();
        for(EnumFacing side : EnumFacing.values()){
            BlockPos pos = this.getPos().offset(side);
            TileEntity tile = this.worldObj.getTileEntity(pos);
            if(tile != null && !(tile instanceof TileEntityTransreceiverRelay)){
                if(tile instanceof IEnergyReceiver){
                    this.receiversAround.put(side, tile);

                    TileEntity oldTile = old.get(side);
                    if(oldTile == null || !tile.equals(oldTile)){
                        change = true;
                    }
                }
            }
        }

        if(change){
            Network network = PlentifulMiscAPI.connectionHandler.getNetworkFor(this.getPos(), this.getWorld());
            if(network != null){
                network.changeAmount++;
            }
        }
    }

    @Override
    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        super.readSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);

            NBTTagList list = compound.getTagList("Connections", 10);
            if(!list.hasNoTags()){
                for(int i = 0; i < list.tagCount(); i++){
                    ConnectionPair pair = new ConnectionPair();
                    pair.readFromNBT(list.getCompoundTagAt(i));
                    PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], this.type, this.worldObj, pair.doesSuppressRender());
                }
            }
        }
    }

    @Override
    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        super.writeSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            NBTTagList list = new NBTTagList();

            ConcurrentSet<IConnectionPair> connections = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);
            if(connections != null && !connections.isEmpty()){
                for(IConnectionPair pair : connections){
                    NBTTagCompound tag = new NBTTagCompound();
                    pair.writeToNBT(tag);
                    list.appendTag(tag);
                }
            }

            compound.setTag("Connections", list);
        }
    }

    private int transferEnergyToReceiverInNeed(EnumFacing from, Network network, int maxTransfer, boolean simulate){
        int transmitted = 0;
        //Keeps track of all the Laser Relays and Energy Acceptors that have been checked already to make nothing run multiple times
        List<BlockPos> alreadyChecked = new ArrayList<BlockPos>();

        List<TileEntityTransreciverRelayEnergy> relaysThatWork = new ArrayList<TileEntityTransreciverRelayEnergy>();
        int totalReceiverAmount = 0;

        for(IConnectionPair pair : network.connections){
            for(BlockPos relay : pair.getPositions()){
                if(relay != null && !alreadyChecked.contains(relay)){
                    alreadyChecked.add(relay);
                    TileEntity relayTile = this.worldObj.getTileEntity(relay);
                    if(relayTile instanceof TileEntityTransreciverRelayEnergy){
                        TileEntityTransreciverRelayEnergy theRelay = (TileEntityTransreciverRelayEnergy)relayTile;
                        int amount = theRelay.receiversAround.size();
                        if(amount > 0){
                            relaysThatWork.add(theRelay);
                            totalReceiverAmount += amount;
                        }
                    }
                }
            }
        }



        if(totalReceiverAmount > 0 && !relaysThatWork.isEmpty()){
            int amountPer = maxTransfer/totalReceiverAmount;
            if(amountPer <= 0){
                amountPer = maxTransfer;
            }

            for(TileEntityTransreciverRelayEnergy theRelay : relaysThatWork){
                double highestLoss = Math.max(theRelay.getLossPercentage(), this.getLossPercentage());
                int lowestCap = Math.min(theRelay.getEnergyCap(), this.getEnergyCap());
                for(Map.Entry<EnumFacing, TileEntity> receiver : theRelay.receiversAround.entrySet()){
                    if(receiver != null){
                        EnumFacing side = receiver.getKey();
                        EnumFacing opp = side.getOpposite();
                        TileEntity tile = receiver.getValue();
                        if(!alreadyChecked.contains(tile.getPos())){
                            alreadyChecked.add(tile.getPos());
                            if(theRelay != this || side != from){
                                if(tile instanceof IEnergyReceiver){
                                    IEnergyReceiver iReceiver = (IEnergyReceiver)tile;
                                    if(iReceiver.canConnectEnergy(opp)){
                                        int theoreticalReceived = iReceiver.receiveEnergy(opp, Math.min(amountPer, lowestCap), true);
                                        if(theoreticalReceived > 0){
                                            int deduct = this.calcDeduction(theoreticalReceived, highestLoss);
                                            if(deduct >= theoreticalReceived){ //Happens with small numbers
                                                deduct = 0;
                                            }

                                            transmitted += iReceiver.receiveEnergy(opp, theoreticalReceived-deduct, simulate);
                                            transmitted += deduct;
                                        }
                                    }
                                }
                                    if(transmitted >= maxTransfer){
                                         return transmitted;
                                    }
                            }
                        }
                    }
                }
            }
        }

        return transmitted;
    }

    private int calcDeduction(int theoreticalReceived, double highestLoss){
        return ConfigBoolValues.TRANSMIT_LOSS.isEnabled() ? MathHelper.ceiling_double_int(theoreticalReceived*(highestLoss/100)) : 0;
    }

    public int getEnergyCap(){
        return CAP;
    }

    public double getLossPercentage(){
        return 5;
    }
}

 

Thanks for your time.

Relatively new to modding.

Currently developing:

https://github.com/LambdaXV/DynamicGenerators

Link to comment
Share on other sites

Hello all,

 

So I have these 'transreceivers' for transporting around energy, however, I'm having trouble saving the connections to NBT.

I do have a error that I caught, which is:

[21:58:54] [Client thread/FATAL]: Registering a TileEntity failed!
java.lang.InstantiationException: com.lambda.plentifulmisc.tile.TileEntityTransreceiverRelay
at java.lang.Class.newInstance(Class.java:427) ~[?:1.8.0_91]
at com.lambda.plentifulmisc.tile.TileEntityBase.register(TileEntityBase.java:66) [TileEntityBase.class:?]
at com.lambda.plentifulmisc.tile.TileEntityBase.init(TileEntityBase.java:57) [TileEntityBase.class:?]
at com.lambda.plentifulmisc.PlentifulMisc.init(PlentifulMisc.java:60) [PlentifulMisc.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:602) [FMLModContainer.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:243) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:221) [LoadController.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [guava-17.0.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [guava-17.0.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [guava-17.0.jar:?]
at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:145) [LoadController.class:?]
at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:795) [Loader.class:?]
at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:330) [FMLClientHandler.class:?]
at net.minecraft.client.Minecraft.startGame(Minecraft.java:560) [Minecraft.class:?]
at net.minecraft.client.Minecraft.run(Minecraft.java:385) [Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
at GradleStart.main(GradleStart.java:26) [start/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:?]
Caused by: java.lang.NoSuchMethodException: com.lambda.plentifulmisc.tile.TileEntityTransreceiverRelay.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[?:1.8.0_91]
at java.lang.Class.newInstance(Class.java:412) ~[?:1.8.0_91]
... 51 more

 

However, this error is from the 'base relay' which gets extended by the energy / fluid relays.

 

Here is the TE Base, where the TE are registered and just makes creating new TE easier:

 

ppackage com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/23/2016.
*/
import com.lambda.plentifulmisc.config.ConfigIntValues;
import com.lambda.plentifulmisc.network.PacketHandler;
import com.lambda.plentifulmisc.network.PacketServerToClient;
import com.lambda.plentifulmisc.util.ModUtil;
import com.lambda.plentifulmisc.util.StringUtil;
import com.lambda.plentifulmisc.util.WorldUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;

public abstract class TileEntityBase extends TileEntity implements ITickable{

    public final String name;
    public boolean isRedstonePowered;
    public boolean isPulseMode;
    protected int ticksElapsed;

    protected TileEntity[] tilesAround = new TileEntity[6];
    protected boolean hasSavedDataOnChangeOrWorldStart;

    public TileEntityBase(String name){
        this.name = name;
    }

    public static void init(){
        ModUtil.LOGGER.info("Registering TileEntities...");

        register(TileEntityCoalGenerator.class);
        register(TileEntityEnergeticFab.class);
        register(TileEntitySolarGenerator.class);
        register(TileEntityRefinery.class);
        register(TileEntityElectricFurnace.class);
        register(TileEntityCrusher.class);
        register(TileEntityAtomicDiffuser.class);
        register(TileEntityDigger.class);

        register(TileEntityTransreceiverRelay.class);
        register(TileEntityTransreceiverFluid.class);
        register(TileEntityTransreceiverRelayEnergyAdv.class);
        register(TileEntityTransreciverRelayEnergy.class);

    }

    private static void register(Class<? extends TileEntityBase> tileClass){
        try{
            String name = ModUtil.MOD_ID+":"+tileClass.newInstance().name;
            GameRegistry.registerTileEntity(tileClass, name);
        }
        catch(Exception e){
            ModUtil.LOGGER.fatal("Registering a TileEntity failed!", e);
        }
    }

    @Override
    public final NBTTagCompound writeToNBT(NBTTagCompound compound){
        this.writeSyncableNBT(compound, NBTType.SAVE_TILE);
        return compound;
    }

    @Override
    public final void readFromNBT(NBTTagCompound compound){
        this.readSyncableNBT(compound, NBTType.SAVE_TILE);
    }

    @Override
    public final SPacketUpdateTileEntity getUpdatePacket(){
        NBTTagCompound compound = new NBTTagCompound();
        this.writeSyncableNBT(compound, NBTType.SYNC);
        return new SPacketUpdateTileEntity(this.pos, -1, compound);
    }

    @Override
    public final void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt){
        this.readSyncableNBT(pkt.getNbtCompound(), NBTType.SYNC);
    }

    @Override
    public final NBTTagCompound getUpdateTag(){
        NBTTagCompound compound = new NBTTagCompound();
        this.writeSyncableNBT(compound, NBTType.SYNC);
        return compound;
    }

    @Override
    public final void handleUpdateTag(NBTTagCompound compound){
        this.readSyncableNBT(compound, NBTType.SYNC);
    }

    public final void sendUpdate(){
        if(!this.worldObj.isRemote){
            NBTTagCompound compound = new NBTTagCompound();
            this.writeSyncableNBT(compound, NBTType.SYNC);

            NBTTagCompound data = new NBTTagCompound();
            data.setTag("Data", compound);
            data.setInteger("X", this.pos.getX());
            data.setInteger("Y", this.pos.getY());
            data.setInteger("Z", this.pos.getZ());
            PacketHandler.theNetwork.sendToAllAround(new PacketServerToClient(data, PacketHandler.TILE_ENTITY_HANDLER), new NetworkRegistry.TargetPoint(this.worldObj.provider.getDimension(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), 128));
        }
    }

    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        if(type != NBTType.SAVE_BLOCK){
            super.writeToNBT(compound);
        }

        if(type == NBTType.SAVE_TILE){
            compound.setBoolean("Redstone", this.isRedstonePowered);
            compound.setInteger("TicksElapsed", this.ticksElapsed);
        }
    }

    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        if(type != NBTType.SAVE_BLOCK){
            super.readFromNBT(compound);
        }

        if(type == NBTType.SAVE_TILE){
            this.isRedstonePowered = compound.getBoolean("Redstone");
            this.ticksElapsed = compound.getInteger("TicksElapsed");
        }

    }

    @Override
    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState){
        return !oldState.getBlock().isAssociatedBlock(newState.getBlock());
    }

    public String getDisplayedName(){
        return StringUtil.localize("container."+ModUtil.MOD_ID+"."+this.name+".name");
    }

    @Override
    public ITextComponent getDisplayName(){
        return new TextComponentString(this.getDisplayedName());
    }

    @Override
    public final void update(){
         this.updateEntity();
    }

    public void updateEntity(){
        this.ticksElapsed++;

        if(!this.worldObj.isRemote && worldObj != null){
            if(this instanceof ISharingEnergyProvider){
                ISharingEnergyProvider provider = (ISharingEnergyProvider)this;
                if(provider.doesShareEnergy()){
                    int total = provider.getEnergyToSplitShare();
                    if(total > 0){
                        EnumFacing[] sides = provider.getEnergyShareSides();

                        int amount = total/sides.length;
                        if(amount <= 0){
                            amount = total;
                        }

                        for(EnumFacing side : sides){
                            TileEntity tile = this.tilesAround[side.ordinal()];
                            if(tile != null){
                                WorldUtil.doEnergyInteraction(this, tile, side, amount);
                            }
                        }
                    }
                }
            }

            if(this instanceof ISharingFluidHandler){
                ISharingFluidHandler handler = (ISharingFluidHandler)this;
                if(handler.doesShareFluid()){
                    int total = handler.getMaxFluidAmountToSplitShare();
                    if(total > 0){
                        EnumFacing[] sides = handler.getFluidShareSides();

                        int amount = total/sides.length;
                        if(amount <= 0){
                            amount = total;
                        }

                        for(EnumFacing side : sides){
                            TileEntity tile = this.tilesAround[side.ordinal()];
                            if(tile != null){
                                WorldUtil.doFluidInteraction(this, tile, side, amount);
                            }
                        }
                    }
                }
            }

            if(!this.hasSavedDataOnChangeOrWorldStart){
                if(this.shouldSaveDataOnChangeOrWorldStart()){
                    this.saveDataOnChangeOrWorldStart();
                }

                this.hasSavedDataOnChangeOrWorldStart = true;
            }
        }
    }

    public void saveDataOnChangeOrWorldStart(){
        for(EnumFacing side : EnumFacing.values()){
            this.tilesAround[side.ordinal()] = this.worldObj.getTileEntity(this.pos.offset(side));
        }
    }

    public boolean shouldSaveDataOnChangeOrWorldStart(){
        return this instanceof ISharingEnergyProvider || this instanceof ISharingFluidHandler;
    }

    public void setRedstonePowered(boolean powered){
        this.isRedstonePowered = powered;
        this.markDirty();
    }

    public boolean canPlayerUse(EntityPlayer player){
        return player.getDistanceSq(this.getPos().getX()+0.5D, this.pos.getY()+0.5D, this.pos.getZ()+0.5D) <= 64 && !this.isInvalid() && this.worldObj.getTileEntity(this.pos) == this;
    }

    protected boolean sendUpdateWithInterval(){
        if(this.ticksElapsed% 1 == 0){
            this.sendUpdate();
            return true;
        }
        else{
            return false;
        }

    }

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing){
        return this.getCapability(capability, facing) != null;
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing){
        if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
            IFluidHandler tank = this.getFluidHandler(facing);
            if (tank != null) {
                return (T) tank;
            }
        }
        return super.getCapability(capability, facing);
    }

    public IFluidHandler getFluidHandler(EnumFacing facing){
        return null;
    }

    public boolean isRedstoneToggle(){
        return false;
    }

    public void activateOnPulse(){

    }

    public enum NBTType{
        SAVE_TILE,
        SYNC,
        SAVE_BLOCK
    }
}

 

 

Now for the 'TileEntityTransreceiverRelay' , which gets extended by all other transrecievers:

 

 

 

package com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/25/2016.
*/
import com.lambda.api.transmitters.IConnectionPair;
import com.lambda.api.PlentifulMiscAPI;
import com.lambda.api.transmitters.TransreceiversType;
import com.lambda.plentifulmisc.util.misc.ConnectionPair;
import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.AxisAlignedBB;

import java.util.Set;

public abstract class TileEntityTransreceiverRelay extends TileEntityBase{

    public static final int MAX_DISTANCE = 15;

    public final TransreceiversType type;

    private Set<IConnectionPair> tempConnectionStorage;

    public TileEntityTransreceiverRelay(String name, TransreceiversType type){
        super(name);
        this.type = type;
    }



    @Override
    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        super.readSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);

            NBTTagList list = compound.getTagList("Connections", 10);
            if(!list.hasNoTags()){
                for(int i = 0; i < list.tagCount(); i++){
                    ConnectionPair pair = new ConnectionPair();
                    pair.readFromNBT(list.getCompoundTagAt(i));
                    PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], this.type, this.worldObj, pair.doesSuppressRender());
                }
            }
        }
    }

    @Override
    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        super.writeSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            NBTTagList list = new NBTTagList();

            ConcurrentSet<IConnectionPair> connections = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);
            if(connections != null && !connections.isEmpty()){
                for(IConnectionPair pair : connections){
                    NBTTagCompound tag = new NBTTagCompound();
                    pair.writeToNBT(tag);
                    list.appendTag(tag);
                }
            }

            compound.setTag("Connections", list);
        }
    }
/*
    @Override
    public void updateEntity(){
        super.updateEntity();
        if(this.worldObj.isRemote){
        }
    }

*/
    @Override
    public void invalidate(){
        super.invalidate();
        //This is because Minecraft randomly invalidates tiles on world join and then validates them again
        //We need to compensate for this so that connections don't get broken randomly
        this.tempConnectionStorage = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);

        PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);
    }

    @Override
    public void validate(){
        if(this.tempConnectionStorage != null){
            for(IConnectionPair pair : this.tempConnectionStorage){
                PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], pair.getType(), this.worldObj, pair.doesSuppressRender());
            }
            this.tempConnectionStorage = null;
        }

        super.validate();
    }

    @Override
    public AxisAlignedBB getRenderBoundingBox(){
        return INFINITE_EXTENT_AABB;
    }
}

 

 

 

Now for the 'TileEntityTransreceiverRelayEnergy', I'll just be using this one for example, all of them have the NBT issue, however. In this class, because the original Relay class was outputting an error, I overwrote the NBT READ/WRITE.

package com.lambda.plentifulmisc.tile;

/**
* Created by Blake on 11/25/2016.
*/
import cofh.api.energy.IEnergyReceiver;
import com.lambda.api.transmitters.IConnectionPair;
import com.lambda.api.transmitters.Network;
import com.lambda.api.PlentifulMiscAPI;
import com.lambda.api.transmitters.TransreceiversType;
import com.lambda.plentifulmisc.config.ConfigBoolValues;
import com.lambda.plentifulmisc.util.misc.ConnectionPair;
import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TileEntityTransreciverRelayEnergy extends TileEntityTransreceiverRelay implements ICustomEnergyReceiver{

    public static final int CAP = 1000;
    public final ConcurrentHashMap<EnumFacing, TileEntity> receiversAround = new ConcurrentHashMap<EnumFacing, TileEntity>();

    public TileEntityTransreciverRelayEnergy(String name){
        super(name, TransreceiversType.ENERGY);
    }

    public TileEntityTransreciverRelayEnergy(){
        this("transreceiverRelay");
    }

    @Override
    public int receiveEnergy(EnumFacing from, int maxReceive, boolean simulate){
        return this.transmitEnergy(from, maxReceive, simulate);
    }

    @Override
    public int getEnergyStored(EnumFacing from){
        return 0;
    }

    @Override
    public int getMaxEnergyStored(EnumFacing from){
        return this.getEnergyCap();
    }

    private int transmitEnergy(EnumFacing from, int maxTransmit, boolean simulate){
        int transmitted = 0;
        if(maxTransmit > 0){
            Network network = PlentifulMiscAPI.connectionHandler.getNetworkFor(this.pos, this.worldObj);
            if(network != null){
                transmitted = this.transferEnergyToReceiverInNeed(from, network, maxTransmit, simulate);
            }
        }
        return transmitted;
    }

    @Override
    public boolean canConnectEnergy(EnumFacing from){
        return true;
    }

    @Override
    public boolean shouldSaveDataOnChangeOrWorldStart(){
        return true;
    }

    @Override
    public void saveDataOnChangeOrWorldStart(){
        Map<EnumFacing, TileEntity> old = new HashMap<EnumFacing, TileEntity>(this.receiversAround);
        boolean change = false;

        this.receiversAround.clear();
        for(EnumFacing side : EnumFacing.values()){
            BlockPos pos = this.getPos().offset(side);
            TileEntity tile = this.worldObj.getTileEntity(pos);
            if(tile != null && !(tile instanceof TileEntityTransreceiverRelay)){
                if(tile instanceof IEnergyReceiver){
                    this.receiversAround.put(side, tile);

                    TileEntity oldTile = old.get(side);
                    if(oldTile == null || !tile.equals(oldTile)){
                        change = true;
                    }
                }
            }
        }

        if(change){
            Network network = PlentifulMiscAPI.connectionHandler.getNetworkFor(this.getPos(), this.getWorld());
            if(network != null){
                network.changeAmount++;
            }
        }
    }

    @Override
    public void readSyncableNBT(NBTTagCompound compound, NBTType type){
        super.readSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            PlentifulMiscAPI.connectionHandler.removeRelayFromNetwork(this.pos, this.worldObj);

            NBTTagList list = compound.getTagList("Connections", 10);
            if(!list.hasNoTags()){
                for(int i = 0; i < list.tagCount(); i++){
                    ConnectionPair pair = new ConnectionPair();
                    pair.readFromNBT(list.getCompoundTagAt(i));
                    PlentifulMiscAPI.connectionHandler.addConnection(pair.getPositions()[0], pair.getPositions()[1], this.type, this.worldObj, pair.doesSuppressRender());
                }
            }
        }
    }

    @Override
    public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
        super.writeSyncableNBT(compound, type);

        if(type == NBTType.SYNC){
            NBTTagList list = new NBTTagList();

            ConcurrentSet<IConnectionPair> connections = PlentifulMiscAPI.connectionHandler.getConnectionsFor(this.pos, this.worldObj);
            if(connections != null && !connections.isEmpty()){
                for(IConnectionPair pair : connections){
                    NBTTagCompound tag = new NBTTagCompound();
                    pair.writeToNBT(tag);
                    list.appendTag(tag);
                }
            }

            compound.setTag("Connections", list);
        }
    }

    private int transferEnergyToReceiverInNeed(EnumFacing from, Network network, int maxTransfer, boolean simulate){
        int transmitted = 0;
        //Keeps track of all the Laser Relays and Energy Acceptors that have been checked already to make nothing run multiple times
        List<BlockPos> alreadyChecked = new ArrayList<BlockPos>();

        List<TileEntityTransreciverRelayEnergy> relaysThatWork = new ArrayList<TileEntityTransreciverRelayEnergy>();
        int totalReceiverAmount = 0;

        for(IConnectionPair pair : network.connections){
            for(BlockPos relay : pair.getPositions()){
                if(relay != null && !alreadyChecked.contains(relay)){
                    alreadyChecked.add(relay);
                    TileEntity relayTile = this.worldObj.getTileEntity(relay);
                    if(relayTile instanceof TileEntityTransreciverRelayEnergy){
                        TileEntityTransreciverRelayEnergy theRelay = (TileEntityTransreciverRelayEnergy)relayTile;
                        int amount = theRelay.receiversAround.size();
                        if(amount > 0){
                            relaysThatWork.add(theRelay);
                            totalReceiverAmount += amount;
                        }
                    }
                }
            }
        }



        if(totalReceiverAmount > 0 && !relaysThatWork.isEmpty()){
            int amountPer = maxTransfer/totalReceiverAmount;
            if(amountPer <= 0){
                amountPer = maxTransfer;
            }

            for(TileEntityTransreciverRelayEnergy theRelay : relaysThatWork){
                double highestLoss = Math.max(theRelay.getLossPercentage(), this.getLossPercentage());
                int lowestCap = Math.min(theRelay.getEnergyCap(), this.getEnergyCap());
                for(Map.Entry<EnumFacing, TileEntity> receiver : theRelay.receiversAround.entrySet()){
                    if(receiver != null){
                        EnumFacing side = receiver.getKey();
                        EnumFacing opp = side.getOpposite();
                        TileEntity tile = receiver.getValue();
                        if(!alreadyChecked.contains(tile.getPos())){
                            alreadyChecked.add(tile.getPos());
                            if(theRelay != this || side != from){
                                if(tile instanceof IEnergyReceiver){
                                    IEnergyReceiver iReceiver = (IEnergyReceiver)tile;
                                    if(iReceiver.canConnectEnergy(opp)){
                                        int theoreticalReceived = iReceiver.receiveEnergy(opp, Math.min(amountPer, lowestCap), true);
                                        if(theoreticalReceived > 0){
                                            int deduct = this.calcDeduction(theoreticalReceived, highestLoss);
                                            if(deduct >= theoreticalReceived){ //Happens with small numbers
                                                deduct = 0;
                                            }

                                            transmitted += iReceiver.receiveEnergy(opp, theoreticalReceived-deduct, simulate);
                                            transmitted += deduct;
                                        }
                                    }
                                }
                                    if(transmitted >= maxTransfer){
                                         return transmitted;
                                    }
                            }
                        }
                    }
                }
            }
        }

        return transmitted;
    }

    private int calcDeduction(int theoreticalReceived, double highestLoss){
        return ConfigBoolValues.TRANSMIT_LOSS.isEnabled() ? MathHelper.ceiling_double_int(theoreticalReceived*(highestLoss/100)) : 0;
    }

    public int getEnergyCap(){
        return CAP;
    }

    public double getLossPercentage(){
        return 5;
    }
}

 

Thanks for your time.

Your TE has to have a 0 argument constructor.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

java.lang.InstantiationException: com.lambda.plentifulmisc.tile.TileEntityTransreceiverRelay

 

You can't instantiate an abstract class.

TileEntityTransreceiverRelay

is abstract. So you can't make an instance of that class.

 

Also, only register the actual

TileEntity

classes that are going to be placed in the world. So don't register

TileEntityTransreceiverRelay

, in the same way the

TileEntity

class isn't registered too.

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

 

1.12 -> 1.13 primer by williewillus.

 

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

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

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