Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Energy conduit round robin. #339

Merged
merged 3 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class EnderConduitTypes {
public static final ResourceLocation ICON_TEXTURE = EnderIO.loc("textures/gui/conduit_icon.png");
public static final RegistryObject<? extends IConduitType<?>> ENERGY = ConduitTypes.CONDUIT_TYPES.register(
"energy_conduit",
() -> new SimpleConduitType<>(EnderIO.loc("block/conduit/energy"), new EnergyConduitTicker(), IExtendedConduitData.EmptyExtendedConduitData::new,
() -> new SimpleConduitType<>(EnderIO.loc("block/conduit/energy"), new EnergyConduitTicker(), EnergyExtendedData::new,
new IClientConduitData.Simple<>(ICON_TEXTURE, new Vector2i(0, 24)), IConduitMenuData.ENERGY));

public static final RegistryObject<FluidConduitType> FLUID = fluidConduit("fluid_conduit", 50, false, new Vector2i(0, 120));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
import dev.gigaherz.graph3.Mergeable;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
import org.apache.commons.lang3.function.TriFunction;

import java.util.List;
Expand All @@ -24,26 +27,37 @@ public EnergyConduitTicker() {
public void tickCapabilityGraph(IConduitType<?> type, List<CapabilityConnection> inserts, List<CapabilityConnection> extracts, ServerLevel level,
Graph<Mergeable.Dummy> graph, TriFunction<ServerLevel, BlockPos, ColorControl, Boolean> isRedstoneActive) {

int availableForExtraction = 0;
for (IEnergyStorage extract : extracts.stream().map(e -> e.cap).toList()) {
availableForExtraction += extract.extractEnergy(extract.getEnergyStored(), true);
}
toNextExtract:
for (CapabilityConnection extract : extracts) {
IEnergyStorage extractHandler = extract.cap;
int availableForExtraction = extractHandler.extractEnergy(Integer.MAX_VALUE, true);
if (availableForExtraction <= 0)
continue;
EnergyExtendedData.EnergySidedData sidedExtractData = extract.data.castTo(EnergyExtendedData.class).compute(extract.direction);

int inserted = 0;
for (IEnergyStorage insert : inserts.stream().map(e -> e.cap).toList()) {
inserted += insert.receiveEnergy(availableForExtraction - inserted, false);
if (inserted == availableForExtraction)
break;
}
if (inserts.size() <= sidedExtractData.rotatingIndex) {
sidedExtractData.rotatingIndex = 0;
}

for (IEnergyStorage extract : extracts.stream().map(e -> e.cap).toList()) {
inserted -= extract.extractEnergy(inserted, false);
if (inserted <= 0)
break;
}
for (int j = 0; j < sidedExtractData.rotatingIndex; j++) {
//empty lists are verified in ICapabilityAwareConduitTicker
//this moves the first element to the back to give a new cap the next time this is called
inserts.add(inserts.remove(0));
}
Rover656 marked this conversation as resolved.
Show resolved Hide resolved

for (int j = 0; j < inserts.size(); j++) {
CapabilityConnection insert = inserts.get(j);

int inserted = insert.cap.receiveEnergy(availableForExtraction, false);
extractHandler.extractEnergy(inserted, false);

if (inserted == availableForExtraction) {
sidedExtractData.rotatingIndex += j + 1;
continue toNextExtract;
}

if (inserted > 0) {
EnderIO.LOGGER.info("didn't extract all energy that was inserted, investigate the dupe bug");
availableForExtraction -= inserted;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.enderio.conduits.common.types;

import com.enderio.api.conduit.IExtendedConduitData;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import org.jetbrains.annotations.Nullable;

import java.util.EnumMap;
import java.util.Map;

public class EnergyExtendedData implements IExtendedConduitData<EnergyExtendedData> {

private final Map<Direction, EnergySidedData> energySidedData = new EnumMap<>(Direction.class);

@Override
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
for (Direction direction: Direction.values()) {
@Nullable EnergySidedData sidedData = energySidedData.get(direction);
if (sidedData != null) {
tag.put(direction.name(), sidedData.toNbt());
}
}
return tag;
}

@Override
public void deserializeNBT(CompoundTag nbt) {
for (Direction direction: Direction.values()) {
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
if (nbt.contains(direction.name())) {
energySidedData.put(direction, EnergySidedData.fromNbt(nbt.getCompound(direction.name())));
}
}
}

public EnergySidedData get(Direction direction) {
return energySidedData.getOrDefault(direction, new EnergySidedData());
}
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
public EnergySidedData compute(Direction direction) {
return energySidedData.computeIfAbsent(direction, dir -> new EnergySidedData());
}

public static class EnergySidedData {
public int rotatingIndex = 0;

// region Serialization

private static final String KEY_ROTATING_INDEX = "RotatingIndex";

private CompoundTag toNbt() {
CompoundTag nbt = new CompoundTag();
nbt.putInt(KEY_ROTATING_INDEX, rotatingIndex);
return nbt;
}

private static EnergySidedData fromNbt(CompoundTag nbt) {
EnergySidedData sidedData = new EnergySidedData();
if (nbt.contains(KEY_ROTATING_INDEX))
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
sidedData.rotatingIndex= nbt.getInt(KEY_ROTATING_INDEX);
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
return sidedData;
}

// endregion
}
}