Jump to content

Recommended Posts

Posted

Hey there!

 

So I'm running into a bit of an issue getting all connected TEs, and sending energy to them.

 

With the current system I had, it would send it to the closest one, making the rest of the TEs on the line, not receive power. I have a working prototype, however, it seems to update the list every update tick, which makes since. However, having this happens makes the power transfer incredibly slow and causes about 4-5 frame drops. I know there is a more efficient way of doing so, just looking for some pointers.

 

Please keep in mind, that this is all a prototype, I honestly dont know much about coding this game, so some stuff might looked fucked up and wrong. Please keep an open mind :)

 

Here is the TE code:

public class TileEntityPipeEnergy extends TileEntityBase implements ITickable, IEnergyReceiver, IEnergyProvider {

    public EnergyStorage storage = new EnergyStorage(16000);
    public static int SENDPERTICK = 16000;

    public final ConcurrentHashMap<EnumFacing, TileEntity> cablesAround = new ConcurrentHashMap<EnumFacing, TileEntity>();


    public ArrayList<TileEntity> connectionList = new ArrayList();

    public TileEntityPipeEnergy() {
        super("energypipe");
    }

    @Override
    public void updateEntity() {
        super.updateEntity();
        System.out.print(connectionList.size());
        int energyStored = getEnergyStored(EnumFacing.DOWN);
        for (EnumFacing facing : EnumFacing.values()) {
            BlockPos pos = getPos().offset(facing);
            TileEntity te = worldObj.getTileEntity(pos);
            if (acceptableTE(te)) {
                EnumFacing opposite = facing.getOpposite();
                int rfToGive = SENDPERTICK <= energyStored ? SENDPERTICK : energyStored;
                int received;
                if (te instanceof IEnergyConnection) {
                    IEnergyConnection connection = (IEnergyConnection) te;
                    if (connection.canConnectEnergy(opposite)) {
                        received = receiveEnergy(te, opposite, rfToGive);
                        cablesAround.put(facing, te);
                    } else {
                        received = 0;
                        cablesAround.remove(facing, te);
                    }
                } else {
                    received = receiveEnergy(te, opposite, rfToGive);
                }
                energyStored -= storage.extractEnergy(received, false);
                if (energyStored <= 0) {
                    break;
                }
            }
        }

        for (Map.Entry<EnumFacing, TileEntity> receiver : cablesAround.entrySet()) {
            connectionList.add(receiver.getValue());
        }
    }

    public int receiveEnergy(TileEntity tileEntity, EnumFacing from, int maxReceive) {
        for(int i = 0; i < connectionList.size(); i++) {
            if (tileEntity instanceof IEnergyReceiver) {
                return ((IEnergyReceiver) tileEntity).receiveEnergy(from, maxReceive / connectionList.size(), false);
            } else if (tileEntity != null && tileEntity.hasCapability(CapabilityEnergy.ENERGY, from)) {
                net.minecraftforge.energy.IEnergyStorage capability = tileEntity.getCapability(CapabilityEnergy.ENERGY, from);
                if (capability.canReceive()) {
                    return capability.receiveEnergy(maxReceive / connectionList.size(), false);
                }
            }
        }
        return 0;
    }

    public static boolean acceptableTE(TileEntity te) {
        return te instanceof IEnergyHandler || (te != null && te.hasCapability(CapabilityEnergy.ENERGY, null));
    }

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

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


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

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

    public int getEnergyStored() {
        return storage.getEnergyStored();
    }

    public int getMaxEnergyStored() {
        return storage.getMaxEnergyStored();
    }

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

    @Override
    public int extractEnergy(EnumFacing from, int maxExtract, boolean simulate) {
        return storage.extractEnergy(maxExtract, simulate);
    }

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


}

Relatively new to modding.

Currently developing:

https://github.com/LambdaXV/DynamicGenerators

Posted

Normally I think others have built a "Consumer" and "Provider" system where they use transports (wires) to connect them. Seems like you're using each wire or "pipe" to store power per instance (or piece of wire) when you should more or less have Batteries, Generators, Relays, etc simply "look" for Consumers that they can reach via wires, and give them power.

 

And if possible save a map of the network (Power generator can reach a light, and a grinder) issue comes now of when the wires are disrupted or changed or something else is added to the network. If you find that your power system as it is now, can kill 4-5 frames aka show visible lag, from going through the process of using power you may wish to space out when things happen across multiple ticks, remember 20 MC ticks is 1 second. If power transfer can move about 5-10 blocks per tick, you can have your power move 100-200 blocks a second.

 

I guess some things to keep in mind is:

When should the network (connections) be remapped (what should trigger it, does it need to be per tick?)

Does power need to be in each wire, or just a controller.

Can or should power be able to loop amongst itself? (closed loop of wire)

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.