diff --git a/src/main/java/appeng/core/api/definitions/ApiParts.java b/src/main/java/appeng/core/api/definitions/ApiParts.java index bfb7f26ba..6dbb09604 100644 --- a/src/main/java/appeng/core/api/definitions/ApiParts.java +++ b/src/main/java/appeng/core/api/definitions/ApiParts.java @@ -22,6 +22,7 @@ import java.util.function.Function; import appeng.fluids.parts.*; import appeng.parts.automation.*; +import appeng.parts.p2p.*; import net.minecraft.item.ItemStack; import appeng.api.definitions.IItemDefinition; @@ -137,26 +138,21 @@ public final class ApiParts implements IParts { ConversionMonitorPart::new); this.iface = createPart("cable_interface", InterfacePart.class, InterfacePart::new); this.fluidIface = createPart("cable_fluid_interface", FluidInterfacePart.class, FluidInterfacePart::new); -// FIXME FABRIC this.p2PTunnelME = createPart("me_p2p_tunnel", MEP2PTunnelPart.class, MEP2PTunnelPart::new); -// FIXME FABRIC this.p2PTunnelRedstone = createPart("redstone_p2p_tunnel", RedstoneP2PTunnelPart.class, -// FIXME FABRIC RedstoneP2PTunnelPart::new); -// FIXME FABRIC this.p2PTunnelItems = createPart("item_p2p_tunnel", ItemP2PTunnelPart.class, ItemP2PTunnelPart::new); -// FIXME FABRIC this.p2PTunnelFluids = createPart("fluid_p2p_tunnel", FluidP2PTunnelPart.class, FluidP2PTunnelPart::new); + this.p2PTunnelME = createPart("me_p2p_tunnel", MEP2PTunnelPart.class, MEP2PTunnelPart::new); + this.p2PTunnelRedstone = createPart("redstone_p2p_tunnel", RedstoneP2PTunnelPart.class, + RedstoneP2PTunnelPart::new); + this.p2PTunnelItems = createPart("item_p2p_tunnel", ItemP2PTunnelPart.class, ItemP2PTunnelPart::new); + this.p2PTunnelFluids = createPart("fluid_p2p_tunnel", FluidP2PTunnelPart.class, FluidP2PTunnelPart::new); // FIXME FABRIC this.p2PTunnelEU = null; // FIXME createPart( "ic2_p2p_tunnel", PartType.P2P_TUNNEL_IC2, // FIXME FABRIC // PartP2PIC2Power.class, PartP2PIC2Power::new); // FIXME FABRIC this.p2PTunnelFE = createPart("fe_p2p_tunnel", FEP2PTunnelPart.class, FEP2PTunnelPart::new); -// FIXME FABRIC this.p2PTunnelLight = createPart("light_p2p_tunnel", LightP2PTunnelPart.class, LightP2PTunnelPart::new); + this.p2PTunnelLight = createPart("light_p2p_tunnel", LightP2PTunnelPart.class, LightP2PTunnelPart::new); this.interfaceTerminal = createPart("interface_terminal", InterfaceTerminalPart.class, InterfaceTerminalPart::new); this.fluidTerminal = createPart("fluid_terminal", FluidTerminalPart.class, FluidTerminalPart::new); - this.p2PTunnelME = null; - this.p2PTunnelRedstone = null; - this.p2PTunnelItems = null; - this.p2PTunnelFluids = null; this.p2PTunnelEU = null; this.p2PTunnelFE = null; - this.p2PTunnelLight = null; this.registry = null; this.partModels = null; diff --git a/src/unported/java/appeng/parts/p2p/FluidP2PTunnelPart.java b/src/main/java/appeng/parts/p2p/FluidP2PTunnelPart.java similarity index 52% rename from src/unported/java/appeng/parts/p2p/FluidP2PTunnelPart.java rename to src/main/java/appeng/parts/p2p/FluidP2PTunnelPart.java index d451615da..4e0636219 100644 --- a/src/unported/java/appeng/parts/p2p/FluidP2PTunnelPart.java +++ b/src/main/java/appeng/parts/p2p/FluidP2PTunnelPart.java @@ -18,37 +18,30 @@ package appeng.parts.p2p; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; - -import javax.annotation.Nonnull; - +import alexiil.mc.lib.attributes.AttributeList; +import alexiil.mc.lib.attributes.Simulation; +import alexiil.mc.lib.attributes.fluid.FluidAttributes; +import alexiil.mc.lib.attributes.fluid.FluidInsertable; +import alexiil.mc.lib.attributes.fluid.FluidVolumeUtil; +import alexiil.mc.lib.attributes.fluid.amount.FluidAmount; +import alexiil.mc.lib.attributes.fluid.volume.FluidKey; import alexiil.mc.lib.attributes.fluid.volume.FluidVolume; -import net.minecraft.fluid.Fluid; -import net.minecraft.item.ItemStack; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; - import appeng.api.parts.IPartModel; import appeng.items.parts.PartModels; import appeng.me.GridAccessException; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; -public class FluidP2PTunnelPart extends P2PTunnelPart implements IFluidHandler { +import java.util.*; + +public class FluidP2PTunnelPart extends P2PTunnelPart implements FluidInsertable { private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_fluids"); private static final ThreadLocal> DEPTH = new ThreadLocal<>();; - private LazyOptional cachedTank; - private int tmpUsed; + private FluidInsertable cachedTank; public FluidP2PTunnelPart(final ItemStack is) { super(is); @@ -80,14 +73,9 @@ public class FluidP2PTunnelPart extends P2PTunnelPart implem } } - @SuppressWarnings("unchecked") @Override - public LazyOptional getCapability(Capability capabilityClass) { - if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { - return (LazyOptional) LazyOptional.of(() -> this); - } - - return super.getCapability(capabilityClass); + public void addAllAttributes(AttributeList to) { + to.offer(this); } @Override @@ -96,118 +84,81 @@ public class FluidP2PTunnelPart extends P2PTunnelPart implem } @Override - public int getTanks() { - return 0; - } - - @Override - @Nonnull - public FluidVolume getFluidInTank(int tank) { - return FluidVolumeUtil.EMPTY; - } - - @Override - public int getTankCapacity(int tank) { - return 1000; - } - - @Override - public boolean isFluidValid(int tank, @Nonnull FluidVolume stack) { - return false; - } - - @Override - public int fill(FluidVolume resource, FluidAction action) { + public FluidVolume attemptInsertion(FluidVolume fluid, Simulation simulation) { final Deque stack = this.getDepth(); for (final FluidP2PTunnelPart t : stack) { if (t == this) { - return 0; + return fluid; } } stack.push(this); - final List list = this.getOutputs(resource.getFluidKey()); - int requestTotal = 0; + final List list = this.getOutputs(fluid.getFluidKey()); + FluidAmount requestTotal = FluidAmount.ZERO; Iterator i = list.iterator(); while (i.hasNext()) { final FluidP2PTunnelPart l = i.next(); - final IFluidHandler tank = l.getTarget().orElse(null); + final FluidInsertable tank = l.getTarget(); + FluidAmount inserted; if (tank != null) { - l.tmpUsed = tank.fill(resource.copy(), FluidAction.SIMULATE); + inserted = fluid.amount().sub(tank.attemptInsertion(fluid.copy(), Simulation.SIMULATE).amount()); } else { - l.tmpUsed = 0; + inserted = FluidAmount.ZERO; } - if (l.tmpUsed <= 0) { + if (inserted.isZero()) { i.remove(); } else { - requestTotal += l.tmpUsed; + requestTotal = requestTotal.add(inserted); } } - if (requestTotal <= 0) { + if (requestTotal.isZero()) { if (stack.pop() != this) { throw new IllegalStateException("Invalid Recursion detected."); } - return 0; + return fluid; } - if (action == FluidAction.EXECUTE) { + if (simulation != Simulation.ACTION) { if (stack.pop() != this) { throw new IllegalStateException("Invalid Recursion detected."); } - return Math.min(resource.getAmount(), requestTotal); + return fluid.copy().split(fluid.amount().min(requestTotal)); } - int available = resource.getAmount(); + FluidAmount remaining = fluid.amount(); i = list.iterator(); - int used = 0; - while (i.hasNext() && available > 0) { + while (i.hasNext() && !remaining.isZero()) { final FluidP2PTunnelPart l = i.next(); - final FluidVolume insert = resource.copy(); - insert.setAmount((int) Math.ceil(insert.getAmount() * ((double) l.tmpUsed / (double) requestTotal))); - if (insert.getAmount() > available) { - insert.setAmount(available); + FluidVolume insert = fluid.withAmount( + fluid.amount().div(list.size()) + ); + if (insert.amount().isGreaterThan(remaining)) { + insert = insert.withAmount(remaining); } - final IFluidHandler tank = l.getTarget().orElse(null); + FluidInsertable tank = l.getTarget(); if (tank != null) { - l.tmpUsed = tank.fill(insert.copy(), action); - } else { - l.tmpUsed = 0; + remaining = remaining.sub(insert.amount().sub(tank.attemptInsertion(insert, Simulation.ACTION).amount())); } - - available -= insert.getAmount(); - used += l.tmpUsed; } if (stack.pop() != this) { throw new IllegalStateException("Invalid Recursion detected."); } - return used; - } - - @Override - @Nonnull - public FluidVolume drain(FluidVolume resource, FluidAction action) { - return FluidVolumeUtil.EMPTY; - } - - @Override - @Nonnull - public FluidVolume drain(int maxDrain, FluidAction action) { - return FluidVolumeUtil.EMPTY; + return remaining.isZero() ? FluidVolumeUtil.EMPTY : fluid.withAmount(remaining); } private Deque getDepth() { @@ -220,12 +171,12 @@ public class FluidP2PTunnelPart extends P2PTunnelPart implem return s; } - private List getOutputs(final Fluid input) { + private List getOutputs(final FluidKey input) { final List outs = new ArrayList<>(); try { for (final FluidP2PTunnelPart l : this.getOutputs()) { - final IFluidHandler handler = l.getTarget().orElse(null); + final FluidInsertable handler = l.getTarget(); if (handler != null) { outs.add(l); @@ -238,7 +189,7 @@ public class FluidP2PTunnelPart extends P2PTunnelPart implem return outs; } - private LazyOptional getTarget() { + private FluidInsertable getTarget() { if (!this.getProxy().isActive()) { return null; } @@ -247,16 +198,7 @@ public class FluidP2PTunnelPart extends P2PTunnelPart implem return this.cachedTank; } - final BlockEntity te = this.getTile().getWorld() - .getBlockEntity(this.getTile().getPos().offset(this.getSide().getFacing())); - - if (te != null && te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, - this.getSide().getFacing().getOpposite()).isPresent()) { - return this.cachedTank = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, - this.getSide().getFacing().getOpposite()); - } - - return null; + return this.cachedTank = FluidAttributes.INSERTABLE.getFirstOrNullFromNeighbour(this.getTile(), this.getSide().getFacing()); } } diff --git a/src/unported/java/appeng/parts/p2p/ItemP2PTunnelPart.java b/src/main/java/appeng/parts/p2p/ItemP2PTunnelPart.java similarity index 73% rename from src/unported/java/appeng/parts/p2p/ItemP2PTunnelPart.java rename to src/main/java/appeng/parts/p2p/ItemP2PTunnelPart.java index a727c437f..d2b96046a 100644 --- a/src/unported/java/appeng/parts/p2p/ItemP2PTunnelPart.java +++ b/src/main/java/appeng/parts/p2p/ItemP2PTunnelPart.java @@ -18,22 +18,11 @@ package appeng.parts.p2p; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; - +import alexiil.mc.lib.attributes.AttributeList; +import alexiil.mc.lib.attributes.CacheInfo; import alexiil.mc.lib.attributes.item.FixedItemInv; -import alexiil.mc.lib.attributes.item.impl.EmptyFixedItemInv; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.CapabilityItemHandler; - +import alexiil.mc.lib.attributes.item.ItemAttributes; +import alexiil.mc.lib.attributes.item.impl.CombinedFixedItemInv; import appeng.api.networking.IGridNode; import appeng.api.networking.events.MENetworkBootingStatusChange; import appeng.api.networking.events.MENetworkChannelsChanged; @@ -48,9 +37,15 @@ import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.cache.helpers.TunnelCollection; import appeng.util.Platform; -import appeng.util.inv.WrapperChainedItemHandler; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; -public class ItemP2PTunnelPart extends P2PTunnelPart implements FixedItemInv, IGridTickable { +import java.util.ArrayList; +import java.util.List; + +public class ItemP2PTunnelPart extends P2PTunnelPart implements IGridTickable { private static final float POWER_DRAIN = 2.0f; private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_items"); private boolean partVisited = false; @@ -63,6 +58,7 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen private int oldSize = 0; private boolean requested; private FixedItemInv cachedInv; + private List cachedInvs = new ArrayList<>(); public ItemP2PTunnelPart(final ItemStack is) { super(is); @@ -71,6 +67,7 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen @Override public void onneighborUpdate(BlockView w, BlockPos pos, BlockPos neighbor) { this.cachedInv = null; + this.cachedInvs.clear(); final ItemP2PTunnelPart input = this.getInput(); if (input != null && this.isOutput()) { input.onTunnelNetworkChange(); @@ -90,7 +87,7 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen try { itemTunnels = this.getOutputs(); } catch (final GridAccessException e) { - return EmptyFixedItemInv.INSTANCE; + return null; } for (final ItemP2PTunnelPart t : itemTunnels) { @@ -104,7 +101,8 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen } } - return this.cachedInv = new WrapperChainedItemHandler(outs.toArray(new FixedItemInv[outs.size()])); + this.cachedInvs = outs; + return this.cachedInv = new CombinedFixedItemInv<>(outs); } private FixedItemInv getOutputInv() { @@ -113,12 +111,10 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen this.partVisited = true; if (this.getProxy().isActive()) { final Direction facing = this.getSide().getFacing(); - final BlockEntity te = this.getTile().getWorld().getBlockEntity(this.getTile().getPos().offset(facing)); - - if (te != null) { - ret = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()) - .orElse(ret); - } + ret = ItemAttributes.FIXED_INV.getFirstOrNullFromNeighbour( + this.getTile(), + facing + ); } this.partVisited = false; } @@ -134,8 +130,12 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen public TickRateModulation tickingRequest(final IGridNode node, final int ticksSinceLastCall) { final boolean wasReq = this.requested; - if (this.requested && this.cachedInv != null) { - ((WrapperChainedItemHandler) this.cachedInv).cycleOrder(); + if (this.requested && !this.cachedInvs.isEmpty()) { + // Don't modify the old list + this.cachedInvs = new ArrayList<>(this.cachedInvs); + FixedItemInv lastInv = this.cachedInvs.remove(this.cachedInvs.size() - 1); + this.cachedInvs.add(0, lastInv); + this.cachedInv = new CombinedFixedItemInv<>(this.cachedInvs); } this.requested = false; @@ -195,44 +195,9 @@ public class ItemP2PTunnelPart extends P2PTunnelPart implemen } } - @SuppressWarnings("unchecked") @Override - public LazyOptional getCapability(Capability capabilityClass) { - if (capabilityClass == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { - return (LazyOptional) LazyOptional.of(() -> this); - } - - return super.getCapability(capabilityClass); - } - - @Override - public int getSlots() { - return this.getDestination().getSlotCount(); - } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) { - return this.getDestination().isItemValid(slot, stack); - } - - @Override - public ItemStack getStackInSlot(final int i) { - return this.getDestination().getInvStack(i); - } - - @Override - public ItemStack insertItem(final int slot, final ItemStack stack, boolean simulate) { - return this.getDestination().insertItem(slot, stack, simulate); - } - - @Override - public ItemStack extractItem(final int slot, final int amount, boolean simulate) { - return this.getDestination().extractItem(slot, amount, simulate); - } - - @Override - public int getMaxAmount(int slot, ItemStack is) { - return this.getDestination().getMaxAmount(slot, is); + public void addAllAttributes(AttributeList to) { + to.offer(getDestination(), CacheInfo.NOT_CACHABLE); } public float getPowerDrainPerTick() { diff --git a/src/unported/java/appeng/parts/p2p/LightP2PTunnelPart.java b/src/main/java/appeng/parts/p2p/LightP2PTunnelPart.java similarity index 100% rename from src/unported/java/appeng/parts/p2p/LightP2PTunnelPart.java rename to src/main/java/appeng/parts/p2p/LightP2PTunnelPart.java diff --git a/src/unported/java/appeng/parts/p2p/RedstoneP2PTunnelPart.java b/src/main/java/appeng/parts/p2p/RedstoneP2PTunnelPart.java similarity index 100% rename from src/unported/java/appeng/parts/p2p/RedstoneP2PTunnelPart.java rename to src/main/java/appeng/parts/p2p/RedstoneP2PTunnelPart.java