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

Rf machines #220

Merged
merged 18 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package muramasa.antimatter.capability.machine;

import earth.terrarium.botarium.common.energy.base.PlatformItemEnergyManager;
import earth.terrarium.botarium.common.energy.util.EnergyHooks;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
Expand Down Expand Up @@ -203,7 +205,21 @@ public List<Pair<ItemStack, IEnergyHandlerItem>> getChargeableItems() {
for (int i = 0; i < chargeables.getSlots(); i++) {
ItemStack item = chargeables.getStackInSlot(i);
if (!item.isEmpty()) {
TesseractCapUtils.getEnergyHandlerItem(item).ifPresent(e -> list.add(new ObjectObjectImmutablePair<>(item, e)));
TesseractCapUtils.getWrappedEnergyHandlerItem(item).ifPresent(e -> list.add(new ObjectObjectImmutablePair<>(item, e)));
}
}
}
return list;
}

public List<Pair<ItemStack, PlatformItemEnergyManager>> getRFChargeableItems() {
List<Pair<ItemStack, PlatformItemEnergyManager>> list = new ObjectArrayList<>();
if (tile.isServerSide()) {
IItemHandlerModifiable chargeables = getChargeHandler();
for (int i = 0; i < chargeables.getSlots(); i++) {
ItemStack item = chargeables.getStackInSlot(i);
if (!item.isEmpty() && EnergyHooks.isEnergyItem(item)) {
list.add(new ObjectObjectImmutablePair<>(item, EnergyHooks.getItemEnergyManager(item)));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package muramasa.antimatter.capability.machine;

import com.google.common.collect.ImmutableList;
import earth.terrarium.botarium.common.energy.base.PlatformEnergyManager;
import earth.terrarium.botarium.common.energy.base.PlatformItemEnergyManager;
import earth.terrarium.botarium.common.energy.util.EnergyHooks;
import earth.terrarium.botarium.common.item.ItemStackHolder;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import muramasa.antimatter.Ref;
import muramasa.antimatter.capability.Dispatch;
import muramasa.antimatter.capability.IMachineHandler;
import muramasa.antimatter.capability.rf.RFHandler;
import muramasa.antimatter.machine.event.ContentEvent;
import muramasa.antimatter.machine.event.IMachineEvent;
import muramasa.antimatter.machine.event.MachineEvent;
import muramasa.antimatter.tile.TileEntityMachine;
import muramasa.antimatter.util.Utils;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.util.LazyOptional;
import tesseract.api.rf.IRFNode;

import java.util.List;
import java.util.Optional;

public class MachineRFHandler<T extends TileEntityMachine<T>> extends RFHandler implements IMachineHandler, Dispatch.Sided<IRFNode> {
protected final T tile;
protected List<Pair<ItemStack, PlatformItemEnergyManager>> cachedItems = new ObjectArrayList<>();

protected int offsetInsert = 0;
protected int offsetExtract = 0;
public MachineRFHandler(T tile, long energy, long capacity, int maxIn, int maxOut) {
super(energy, capacity, maxIn, maxOut);
this.tile = tile;
}

public MachineRFHandler(T tile, long capacity, boolean isGenerator) {
this(tile, 0, capacity, isGenerator ? 0 : tile.getMachineTier().getVoltage(), isGenerator ? tile.getMachineTier().getVoltage() : 0);
}

public void onUpdate(){
for (Direction dir : Ref.DIRS) {
if (canOutput(dir)) {
BlockEntity tile = this.tile.getLevel().getBlockEntity(this.tile.getBlockPos().relative(dir));
if (tile == null) continue;
Optional<PlatformEnergyManager> handle = EnergyHooks.safeGetBlockEnergyManager(tile, dir.getOpposite());
handle.ifPresent(eh -> Utils.transferEnergy(this, eh));
}
}
}

@Override
public void init() {
this.cachedItems = tile.itemHandler.map(MachineItemHandler::getRFChargeableItems).map(ImmutableList::copyOf).orElse(ImmutableList.of());
}

@Override
public long getMaxCapacity() {
if (canChargeItem()) {
return super.getMaxCapacity() + (cachedItems != null ? cachedItems.stream().map(Pair::right).mapToLong(PlatformItemEnergyManager::getCapacity).sum() : 0);
}
return super.getMaxCapacity();
}

@Override
public long insertEnergy(long maxAmount, boolean simulate) {
int j = 0;
long inserted = super.insertEnergy(maxAmount, simulate);
for (int i = offsetInsert; j < cachedItems.size(); j++, i = (i == cachedItems.size() - 1 ? 0 : (i + 1))) {
PlatformItemEnergyManager handler = cachedItems.get(i).right();
if (!handler.supportsInsertion()) continue;
ItemStack stack = cachedItems.get(i).left();
ItemStackHolder holder = new ItemStackHolder(stack);
long insert = handler.insert(holder, maxAmount, simulate);
if (insert > 0) {
if (holder.isDirty()){ //assumes the item itself did not change
stack.setTag(holder.getStack().getTag());
stack.setCount(holder.getStack().getCount());
}
offsetInsert = (offsetInsert + 1) % cachedItems.size();
inserted += insert;
}
}
if (inserted > 0) {
tile.onMachineEvent(MachineEvent.ENERGY_INPUTTED);
}
return inserted;
}

@Override
public long extractEnergy(long maxAmount, boolean simulate) {
int j = 0;
long extracted = super.extractEnergy(maxAmount, simulate);
for (int i = offsetInsert; j < cachedItems.size(); j++, i = (i == cachedItems.size() - 1 ? 0 : (i + 1))) {
PlatformItemEnergyManager handler = cachedItems.get(i).right();
if (!handler.supportsExtraction()) continue;
ItemStack stack = cachedItems.get(i).left();
ItemStackHolder holder = new ItemStackHolder(stack);
long extract = handler.extract(holder, maxAmount, simulate);
if (extract > 0) {
if (holder.isDirty()){ //assumes the item itself did not change
stack.setTag(holder.getStack().getTag());
stack.setCount(holder.getStack().getCount());
}
offsetInsert = (offsetInsert + 1) % cachedItems.size();
extracted += extract;
}
}
if (extracted > 0) {
tile.onMachineEvent(MachineEvent.ENERGY_INPUTTED);
}
return extracted;
}

@Override
public long getStoredEnergy() {
if (canChargeItem()) {
return super.getStoredEnergy() + (cachedItems != null ? cachedItems.stream().map(Pair::right).mapToLong(PlatformItemEnergyManager::getStoredEnergy).sum() : 0);
}
return super.getStoredEnergy();
}

@Override
public boolean canInput(Direction direction) {
return super.canInput(direction) && tile.getFacing() != direction;
}

public boolean canChargeItem() {
return true;
}

@Override
public void onMachineEvent(IMachineEvent event, Object... data) {
if (event == ContentEvent.ENERGY_SLOT_CHANGED) {
tile.itemHandler.ifPresent(h -> {
cachedItems = h.getRFChargeableItems();
offsetInsert = 0;
offsetExtract = 0;
});
//refreshNet();
}
}

@Override
public LazyOptional<? extends IRFNode> forSide(Direction side) {
return LazyOptional.of(() -> this);
}

@Override
public LazyOptional<? extends IRFNode> forNullSide() {
return LazyOptional.of(() -> this);
}

public void onRemove() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public int getOverclock() {

public long getPower() {
if (activeRecipe == null) return 0;
if (overclock == 0) return activeRecipe.getPower();
if (overclock == 0 || tile.has(MachineFlag.RF)) return activeRecipe.getPower();
//half the duration => overclock ^ 2.
//so if overclock is 2 tiers, we have 1/4 the duration(200 -> 50) but for e.g. 8eu/t this would be
//8*4*4 = 128eu/t.
Expand All @@ -216,7 +216,7 @@ public long getPower() {

protected void calculateDurations() {
maxProgress = activeRecipe.getDuration();
if (!generator) {
if (!generator && !tile.has(MachineFlag.RF)) {
overclock = getOverclock();
this.maxProgress = Math.max(1, maxProgress >> overclock);
}
Expand Down Expand Up @@ -345,6 +345,20 @@ public boolean consumeResourceForRecipe(boolean simulate) {
} else {
return consumeGeneratorResources(simulate);
}
} else if (tile.rfHandler.isPresent()){
if (!generator) {
long power = getPower();
long availableEnergy = tile.rfHandler.map(eh -> eh.getStoredEnergy()).orElse(0L);
if (availableEnergy > 0 && availableEnergy >= power){
if (!simulate){
tile.rfHandler.ifPresent(eh -> eh.setEnergy(availableEnergy - power));
}
return true;
}
return false;
} else {
return consumeRFGeneratorResources(simulate);
}
} else {
return false;
}
Expand Down Expand Up @@ -447,6 +461,33 @@ protected boolean canRecipeContinue() {
return canOutput() && (!activeRecipe.hasInputItems() || tile.itemHandler.map(i -> i.consumeInputs(this.activeRecipe, true).size() > 0).orElse(false)) && (!activeRecipe.hasInputFluids() || tile.fluidHandler.map(t -> t.consumeAndReturnInputs(activeRecipe.getInputFluids(), true).size() > 0).orElse(false));
}

protected boolean consumeRFGeneratorResources(boolean simulate){
if (!activeRecipe.hasInputFluids()) {
throw new RuntimeException("Missing fuel in active generator recipe!");
}
long toConsume = calculateGeneratorConsumption(activeRecipe);
long actualConsume = toConsume;
if (actualConsume == 0 || tile.fluidHandler.map(h -> {
FluidIngredient in = activeRecipe.getInputFluids().get(0);
long amount = in.drainedAmount((int) actualConsume, h, true, true); //h.getInputTanks().drain(new FluidStack(activeRecipe.getInputFluids().get(0).getStacks()[0], (int) actualConsume), IFluidHandler.FluidAction.SIMULATE).getAmount();
if (amount == actualConsume) {
if (!simulate)
in.drain(amount, h, true, false);
return true;
}
return false;
}).orElse(false)) {
//insert power!
if (!simulate) {
tile.rfHandler.ifPresent(r -> {
r.setEnergy(r.getStoredEnergy() + activeRecipe.getPower());
});
}
return true;
}
return false;
}

/*
Helper to consume resources for a generator.
*/
Expand Down Expand Up @@ -513,6 +554,14 @@ protected long calculateGeneratorConsumption(int volt, IRecipe r) {
return Math.max(1, (long) (Math.ceil(offset)));
}

protected long calculateGeneratorConsumption(IRecipe r) {
long amount = r.getInputFluids().get(0).getAmount();
if (currentProgress > 0) {
return 0;
}
return amount;
}

public void resetRecipe() {
this.activeRecipe = null;
this.consumedResources = false;
Expand Down
Loading