Jump to content
  • Home
  • Files
  • Docs
Topics
  • All Content

  • This Topic
  • This Forum

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • Needing help with Forge Energy
Currently Supported: 1.16.X (Latest) and 1.15.X (LTS)
Sign in to follow this  
Followers 0
reu_24

Needing help with Forge Energy

By reu_24, October 31, 2020 in Modder Support

  • Reply to this topic
  • Start new topic

Recommended Posts

reu_24    0

reu_24

reu_24    0

  • Tree Puncher
  • reu_24
  • Members
  • 0
  • 5 posts
Posted October 31, 2020

I'm rather new to modding and I want to create a tech mod. I was using for all my machines FE but it seems like I've been doing something wrong because it doesn't work with other mods that use FE. My implementation works like this:

I have a machine tile entity that has an energy storage as the capability. When it's an energy generator it has a max receive of 0 and a max extract of a non 0 number. If it is a energy consumer it has a max receive of a non 0 number and a max extract of 0. My cable check if there's a tile entitiy with energy capability and remove/give it energy based on the max receive and max extract.

I tried to use one of my generators with my cable and connected it with a Mekanism machine. But it seems like the Mekansim machine has a max receive of 0 so my cable doesn't give any energy to it.

What have I understood wong?

  • Quote

Share this post


Link to post
Share on other sites

diesieben07    7588

diesieben07

diesieben07    7588

  • Reality Controller
  • diesieben07
  • Forum Team
  • 7588
  • 54946 posts
Posted October 31, 2020

Please show your code.

  • Quote

Share this post


Link to post
Share on other sites

reu_24    0

reu_24

reu_24    0

  • Tree Puncher
  • reu_24
  • Members
  • 0
  • 5 posts
Posted October 31, 2020

In the TileEntity:

public abstract class CoalGeneratorTileEntity extends TileEntity implements INamedContainerProvider {

    protected ITextComponent customName;
    protected I inventory;
	protected BaseEnergyStorage energy = new BaseEnergyStorage(getCapacity(), getMaxReceive(), getMaxExtract(), getStartEnergy());
 	public int currentProcessingTime;
	protected boolean isProcessing = false;

    public static final String CURRENT_PROCESSING_TIME = "CurrentProcessingTime";
    public static final String CUSTOM_NAME = "CustomName";

    public CoalGeneratorTileEntity(TileEntityType<?> tileEntityTypeIn) {
        super(tileEntityTypeIn);
		inventory = new BaseItemHandler(1);
    }

	@Override
    public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity player) {
        return new CoalGeneratorContainer(windowId, playerInventory, this, ModContainerTypes.COAL_GENERATOR);
    }

    @Override
    public ITextComponent getDisplayName() {
        return getName();
    }

    public void setCustomName(ITextComponent name) {
        customName = name;
    }

    public ITextComponent getName() {
        return customName != null ? customName : getDefaultName();
    }

    private ITextComponent getDefaultName() {
        return new TranslationTextComponent("container." + TodayAndTomorrow.MOD_ID + "." + "coal_generator");
    }

    @Override
    public void read(CompoundNBT compound) {
        super.read(compound);
        if (compound.contains(CUSTOM_NAME, Constants.NBT.TAG_STRING)) {
            customName = ITextComponent.Serializer.fromJson(compound.getString(CUSTOM_NAME));
        }
        NonNullList<ItemStack> inv = NonNullList.withSize(inventory.getSlots(), ItemStack.EMPTY);
        ItemStackHelper.loadAllItems(compound, inv);
        inventory.setNonNullList(inv);
		energy.readFromNBT(compound);
		currentProcessingTime = compound.getInt(CURRENT_PROCESSING_TIME);
    }

    @Override
    public CompoundNBT write(CompoundNBT compound) {
        super.write(compound);
        if (customName != null) {
            compound.putString("CustomName", ITextComponent.Serializer.toJson(this.customName));
        }

        ItemStackHelper.saveAllItems(compound, inventory.toNonNullList());
		energy.writeToNBT(compound);
		compound.putInt(CURRENT_PROCESSING_TIME, currentProcessingTime);
        return compound;
    }

    public I getInventory() {
        return inventory;
    }

    @Override
    public SUpdateTileEntityPacket getUpdatePacket() {
        CompoundNBT nbt = new CompoundNBT();
        this.write(nbt);
        return new SUpdateTileEntityPacket(this.pos, 0, nbt);
    }

    @Override
    public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
        this.read(pkt.getNbtCompound());
    }

    @Override
    public CompoundNBT getUpdateTag() {
        CompoundNBT nbt = new CompoundNBT();
        this.write(nbt);
        return nbt;
    }

    @Override
    public void handleUpdateTag(CompoundNBT nbt) {
        this.read(nbt);
    }

    @Override
    public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
        LazyOptional<T> inventory = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> inventory));
		if (inventory.isPresent()) {
            return inventory;
        }
        return CapabilityEnergy.ENERGY.orEmpty(cap, LazyOptional.of(() -> energy));
    }

    @Override
    public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity player) {
        return createMenu(windowId, playerInventory, player);
    }

	@Override
    public void tick() {
        boolean dirty = false;

        if (world != null && !world.isRemote()) {
            if ((energy.getMaxEnergyStored() > energy.getEnergyStored() && inventory.getStackInSlot(0).getCount() > 0)
				|| isProcessing) {
                if (currentProcessingTime < getProcessingTime()) {
                    if (currentProcessingTime == 0) {
                        inventory.decrStackSize(0, 1);
        				isProcessing = true;
                    }
                    energy.receiveEnergyRaw(ENERGY_PER_TICK, false);
                    setLit(true);
                    currentProcessingTime++;
                    dirty = true;
                } else {
                    currentProcessingTime = 0;
                    isProcessing = false;
                }
            } else {
                currentProcessingTime = 0;
                setLit(false);
            }
        }

        if (dirty) {
            markDirty();
            world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE);
        }
    }

    protected void setLit(boolean lit) {
        if (getBlockState().getBlock() instanceof LitGuiBlock) {
            world.setBlockState(getPos(), getBlockState().with("lit", lit));
        }
    }
}

BaseEnergyStorage is a class that extends EnergyStorage.

 

In the wire I've gone through all connected wires and checked if a tile entity with energy capacity is there.

public class CopperWireTileEntity extends TileEntity implements ITickableTileEntity {

    boolean[] machineAt = new boolean[6];

    public CopperWireTileEntity(TileEntityType<?> tileEntityTypeIn) {
        super(tileEntityTypeIn);

        Arrays.fill(machineAt, false);
    }

    public CopperWireTileEntity() {
        this(ModTileEntityTypes.COPPER_WIRE.get());
    }

    @Override
    public void tick() {
        updateSide(0, getPos().north(), Direction.NORTH);
        updateSide(1, getPos().east(), Direction.EAST);
        updateSide(2, getPos().south(), Direction.SOUTH);
        updateSide(3, getPos().west(), Direction.WEST);
        updateSide(4, getPos().up(), Direction.UP);
        updateSide(5, getPos().down(), Direction.DOWN);

        int energyAvailable = getEnergyAvailable();
        if (energyAvailable != 0) {
            int takeAway = scatterEnergy(energyAvailable);
            takeAwayEnergy(takeAway, energyAvailable);
        }
    }

    protected void updateSide(int index, BlockPos pos, Direction direction) {
        if (!machineAt[index]) {
            TileEntity tileEntity = world.getTileEntity(pos);
            if (tileEntity != null && tileEntity.getCapability(CapabilityEnergy.ENERGY).isPresent()) {
                machineAt[index] = true;
            }
        } else if (world.getBlockState(pos).getBlock() == Blocks.AIR) {
            machineAt[index] = false;
        }
    }

    protected int getEnergyAvailable() {
        AtomicInteger energyAvailable = new AtomicInteger();
        for (int i = 0; i < machineAt.length; i++) {
            if (machineAt[i]) {
                world.getTileEntity(getBlockPosByIndex(pos, i)).getCapability(CapabilityEnergy.ENERGY).ifPresent((e) -> energyAvailable.addAndGet(e.extractEnergy(Integer.MAX_VALUE, true)));
            }
        }
        return energyAvailable.get();
    }

    protected int scatterEnergy(int energyAvailable) {
        ArrayList<BlockPos> visited = new ArrayList<>();
        ArrayList<IEnergyStorage> outputMachinePositions = new ArrayList<>();
        getOutputMachinesEnergy(getPos(), visited, outputMachinePositions);

        int maxReceives = 0;
        for (IEnergyStorage energy : outputMachinePositions) {
            maxReceives += energy.receiveEnergy(Integer.MAX_VALUE, true);
        }

        if (maxReceives <= energyAvailable) {
            for (IEnergyStorage energy : outputMachinePositions) {
                int sent = energy.receiveEnergy(Integer.MAX_VALUE, false);
            }
            return maxReceives;
        }

        int energyGiven = 0;
        for (IEnergyStorage energy : outputMachinePositions) {
            int energyNeeded = energy.receiveEnergy(Integer.MAX_VALUE, true);
            int energyToGive = (int)((float)energyNeeded / (float)maxReceives * (float)energyAvailable);
            energyGiven += energyToGive;
            int a = energy.receiveEnergy(energyToGive, false);
        }

        return energyGiven;
    }

    protected void takeAwayEnergy(int takeAway, int energyAvailable) {
        for (int i = 0; i < machineAt.length; i++) {
            if (machineAt[i]) {
                world.getTileEntity(getBlockPosByIndex(pos, i)).getCapability(CapabilityEnergy.ENERGY).ifPresent((e) -> {
                    int energyProviding = e.extractEnergy(Integer.MAX_VALUE, true);
                    int energyToTakeAway = (int)((float)energyProviding / (float)energyAvailable * (float)takeAway);
                    e.extractEnergy(energyToTakeAway, false);
                });
            }
        }
    }

    protected void getOutputMachinesEnergy(BlockPos pos, ArrayList<BlockPos> visited, ArrayList<IEnergyStorage> outEnergies) {
        if (!visited.contains(pos)) {
            if (world.getBlockState(pos).getBlock() == BlockInit.COPPER_WIRE.get()) {
                visited.add(pos);
                getOutputMachinesEnergy(pos.north(), visited, outEnergies);
                getOutputMachinesEnergy(pos.east(), visited, outEnergies);
                getOutputMachinesEnergy(pos.south(), visited, outEnergies);
                getOutputMachinesEnergy(pos.west(), visited, outEnergies);
                getOutputMachinesEnergy(pos.up(), visited, outEnergies);
                getOutputMachinesEnergy(pos.down(), visited, outEnergies);
            } else if (world.getTileEntity(pos) != null && world.getTileEntity(pos).getCapability(CapabilityEnergy.ENERGY).isPresent()) {
                AtomicReference<IEnergyStorage> energy = new AtomicReference<>();
                world.getTileEntity(pos).getCapability(CapabilityEnergy.ENERGY).ifPresent(energy::set);
                outEnergies.add(energy.get());
            }
        }
    }

    protected BlockPos getBlockPosByIndex(BlockPos pos, int index) {
        switch (index) {
            case 0:
                return pos.north();
            case 1:
                return pos.east();
            case 2:
                return pos.south();
            case 3:
                return pos.west();
            case 4:
                return pos.up();
            case 5:
                return pos.down();
        }
        throw new IllegalArgumentException("Invalid index: " + index);
    }
}

I thought that the energy consuming machines from other Mods would have EnergyStorge with maxReceive from more that 0 so that I could give them energy. But when i tested it with Mekansim:

int energyNeeded = energy.receiveEnergy(Integer.MAX_VALUE, true);

and energyNeeded was 0 so the wire didn't extract any energy.

  • Quote

Share this post


Link to post
Share on other sites

diesieben07    7588

diesieben07

diesieben07    7588

  • Reality Controller
  • diesieben07
  • Forum Team
  • 7588
  • 54946 posts
Posted October 31, 2020

This is not something that can be debugged by just staring at some code, this needs to be checked in the debugger to see what is actually happening.

  • Quote

Share this post


Link to post
Share on other sites

loordgek    174

loordgek

loordgek    174

  • World Shaper
  • loordgek
  • Members
  • 174
  • 1797 posts
Posted October 31, 2020
1 hour ago, reu_24 said:

.getCapability(CapabilityEnergy.ENERGY)

dont do that use https://github.com/MinecraftForge/MinecraftForge/blob/1.16.x/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java#L41

  • Thanks 1
  • Quote

Share this post


Link to post
Share on other sites

reu_24    0

reu_24

reu_24    0

  • Tree Puncher
  • reu_24
  • Members
  • 0
  • 5 posts
Posted November 1, 2020
20 hours ago, loordgek said:

dont do that use https://github.com/MinecraftForge/MinecraftForge/blob/1.16.x/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java#L41

Thank you! Using this method fixed many bugs. I also figured out that the generator should give the cable the energy instead of the cable taking away energy from the generator. After I fixed that everthing worked.

  • Quote

Share this post


Link to post
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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  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.

    • Insert image from URL
×
  • Desktop
  • Tablet
  • Phone
Sign in to follow this  
Followers 0
Go To Topic Listing



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • bleep_blops
      Forge Installation Problem

      By bleep_blops · Posted just now

      Hello! I'm having a weird problem during installation where when I go to download forge 1.12.2 and try and open it, all it does is download another forge file. I've downloaded forge before and notice that instead of having the forge icon it is instead a the google chrome logo. I'm not sure what is causing this and was hoping you could help me. I also should let you know that I have the newest java downloaded. Thanks!
    • Klarks
      [1.16.4] How i can open a container by clicking on my mob

      By Klarks · Posted 5 minutes ago

      I dont quite understand what you mean by this. I created a new class.      NetworkHooks.openGui((ServerPlayerEntity) playerEntity,new MyModContainer(0,new anonymousInnerClass() { },playerEntity.inventory));     public class anonymousInnerClass implements INamedContainerProvider { @Override public ITextComponent getDisplayName() { return new StringTextComponent("Name"); } @Nullable @Override public Container createMenu(int id, PlayerInventory playerInventory, PlayerEntity playerEntity) { return new MyModContainer(id,playerInventory); } }
    • BobbyLikesCake
      1.16.4 (Heavily decent modded with around 150ish mods) Crash with exit code -1 most of the time and sometimes exit code 0.

      By BobbyLikesCake · Posted 21 minutes ago

      Ok, The debug log is here:  https://pastebin.aquilenet.fr/?b2c84859c3c0ad45#26FCvr6VHB8TKL24Ux83N7G1k1eCNAHhQJNaTuAYKLyB
    • diesieben07
      [1.15.2] Render as 2D icon in GUI, 3D model in hand

      By diesieben07 · Posted 31 minutes ago

      In 1.16 Forge has SeparatePerspectiveModel, which you can trivally port to 1.15.
    • metword
      [1.16.4] Config file will not update.

      By metword · Posted 31 minutes ago

      Thank you all so much. Loading the config was my problem. I think it is all in order now!
  • Topics

    • bleep_blops
      0
      Forge Installation Problem

      By bleep_blops
      Started Just now

    • Klarks
      16
      [1.16.4] How i can open a container by clicking on my mob

      By Klarks
      Started 23 hours ago

    • BobbyLikesCake
      2
      1.16.4 (Heavily decent modded with around 150ish mods) Crash with exit code -1 most of the time and sometimes exit code 0.

      By BobbyLikesCake
      Started 2 hours ago

    • Woodside
      1
      [1.15.2] Render as 2D icon in GUI, 3D model in hand

      By Woodside
      Started 1 hour ago

    • metword
      17
      [1.16.4] Config file will not update.

      By metword
      Started Wednesday at 04:20 PM

  • Who's Online (See full list)

    • vemerion
    • Klarks
    • EnergizedAB
    • BobbyLikesCake
    • DaemonUmbra
    • philip-elsner@gmx.net
    • Telmoun
    • Forix
    • Carzival
    • LexManos
    • RafaMv
    • bleep_blops
    • iiDk_lol
    • Witherking25
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • Needing help with Forge Energy
  • Theme

Copyright © 2019 ForgeDevelopment LLC · Ads by Longitude Ads LLC Powered by Invision Community