diff --git a/src/main/java/gregtech/api/pipenet/FlowChannelManager.java b/src/main/java/gregtech/api/pipenet/FlowChannelManager.java index 7d0c455c25b..c917646803e 100644 --- a/src/main/java/gregtech/api/pipenet/FlowChannelManager.java +++ b/src/main/java/gregtech/api/pipenet/FlowChannelManager.java @@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - import org.jetbrains.annotations.Nullable; import java.util.Map; diff --git a/src/main/java/gregtech/api/pipenet/FlowChannelTicker.java b/src/main/java/gregtech/api/pipenet/FlowChannelTicker.java index c961f6f5210..1318d4eff49 100644 --- a/src/main/java/gregtech/api/pipenet/FlowChannelTicker.java +++ b/src/main/java/gregtech/api/pipenet/FlowChannelTicker.java @@ -2,15 +2,17 @@ import gregtech.api.GTValues; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - import net.minecraft.world.World; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArraySet; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; + import java.lang.ref.WeakReference; +import java.util.Map; import java.util.Set; // Ok, I admit, truly tickless fluidpipes would mean sacrificing behavior. I'd have to make them act like itempipes. @@ -18,22 +20,34 @@ @Mod.EventBusSubscriber(modid = GTValues.MODID) public final class FlowChannelTicker { - private final static Set>> MANAGERS = new ObjectOpenHashSet<>(); + private final static Map>>> MANAGERS = new Object2ObjectOpenHashMap<>(); + private final static Map TICK_COUNTS = new Object2ObjectOpenHashMap<>(); + + private final static Set>> EMPTY = new ObjectArraySet<>(0); @SubscribeEvent - public static void onServerTick(TickEvent.ServerTickEvent event) { - if (FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter() % 20 != 0) return; - for (WeakReference> ref : MANAGERS) { + public static void onWorldTick(TickEvent.WorldTickEvent event) { + if (event.world.isRemote) return; + TICK_COUNTS.compute(event.world, (k, v) -> { + if (v == null) v = 0; + return v % 10 + 1; + }); + if (TICK_COUNTS.get(event.world) != 10) return; + + for (WeakReference> ref : MANAGERS.getOrDefault(event.world, EMPTY)) { FlowChannelManager manager = ref.get(); if (manager != null) { manager.tick(); } else { - MANAGERS.remove(ref); + MANAGERS.get(event.world).remove(ref); } } } - public static void addManager(FlowChannelManager manager) { - MANAGERS.add(new WeakReference<>(manager)); + public static void addManager(World world, FlowChannelManager manager) { + if (!MANAGERS.containsKey(world)) { + MANAGERS.put(world, new ObjectOpenHashSet<>()); + } + MANAGERS.get(world).add(new WeakReference<>(manager)); } } diff --git a/src/main/java/gregtech/api/pipenet/NetGroup.java b/src/main/java/gregtech/api/pipenet/NetGroup.java index 31b920af1f8..cb938c9c0af 100644 --- a/src/main/java/gregtech/api/pipenet/NetGroup.java +++ b/src/main/java/gregtech/api/pipenet/NetGroup.java @@ -3,7 +3,6 @@ import gregtech.api.pipenet.block.IPipeType; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.INBTSerializable; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; diff --git a/src/main/java/gregtech/api/pipenet/WorldPipeFlowNetG.java b/src/main/java/gregtech/api/pipenet/WorldPipeFlowNetG.java index 5d400e940a7..772e9eb35ad 100644 --- a/src/main/java/gregtech/api/pipenet/WorldPipeFlowNetG.java +++ b/src/main/java/gregtech/api/pipenet/WorldPipeFlowNetG.java @@ -1,15 +1,12 @@ package gregtech.api.pipenet; import gregtech.api.pipenet.block.IPipeType; - import gregtech.api.pipenet.tile.TileEntityPipeBase; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - import net.minecraft.nbt.NBTTagCompound; - import net.minecraft.nbt.NBTTagList; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jgrapht.graph.SimpleDirectedWeightedGraph; @@ -65,7 +62,8 @@ public List> getPaths(@Nullable NodeG - implements IDataInfoProvider { + implements IDataInfoProvider { private PipeTankList pipeTankList; private final EnumMap tankLists = new EnumMap<>(EnumFacing.class); @@ -340,7 +336,8 @@ public void readFromNBT(@NotNull NBTTagCompound nbt) { if (stack == null) continue; fluidTanks[i].setFluid(stack); // the best part is that this naturally gives us backwards compatibility. - FluidChannel channel = FluidChannel.getChannelFromGroup(stack.getFluid(), this.getNode().getGroupSafe()); + FluidChannel channel = FluidChannel.getChannelFromGroup(stack.getFluid(), + this.getNode().getGroupSafe()); channel.addSource(this.getNode()); } } diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java b/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java index 97b3ece73d5..773007be383 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java @@ -1,50 +1,6 @@ package gregtech.common.pipelike.fluidpipe.tile; -import gregtech.api.GTValues; -import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.cover.Cover; -import gregtech.api.cover.CoverableView; -import gregtech.api.fluids.FluidConstants; -import gregtech.api.fluids.FluidState; -import gregtech.api.fluids.attribute.AttributedFluid; -import gregtech.api.fluids.attribute.FluidAttribute; -import gregtech.api.metatileentity.IDataInfoProvider; -import gregtech.api.unification.material.properties.FluidPipeProperties; -import gregtech.api.util.EntityDamageUtil; -import gregtech.api.util.TextFormattingUtil; -import gregtech.common.covers.CoverPump; -import gregtech.common.covers.ManualImportExportMode; -import gregtech.common.pipelike.fluidpipe.net.FluidChannel; -import gregtech.common.pipelike.fluidpipe.net.PipeTankList; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.Blocks; -import net.minecraft.init.SoundEvents; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ITickable; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.Style; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; public class TileEntityFluidPipeTickable extends TileEntityFluidPipe implements ITickable { @@ -85,111 +41,111 @@ public boolean supportsTicking() { return true; } -// private void distributeFluid(int channel, FluidTank tank, FluidStack fluid) { -// // Tank, From, Amount to receive -// List tanks = new ArrayList<>(); -// int amount = fluid.amount; -// -// FluidStack maxFluid = fluid.copy(); -// double availableCapacity = 0; -// -// for (byte i = 0, j = (byte) GTValues.RNG.nextInt(6); i < 6; i++) { -// // Get a list of tanks accepting fluids, and what side they're on -// byte side = (byte) ((i + j) % 6); -// EnumFacing facing = EnumFacing.VALUES[side]; -// -// if (!isConnected(facing) || (lastReceivedFrom & (1 << side)) != 0) { -// continue; -// } -// -// TileEntity neighbor = getNeighbor(facing); -// if (neighbor == null) continue; -// IFluidHandler fluidHandler = neighbor.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, -// facing.getOpposite()); -// if (fluidHandler == null) continue; -// -// IFluidHandler pipeTank = tank; -// Cover cover = getCoverableImplementation().getCoverAtSide(facing); -// -// // pipeTank should only be determined by the cover attached to the actual pipe -// if (cover != null) { -// pipeTank = cover.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, pipeTank); -// // Shutter covers return null capability when active, so check here to prevent NPE -// if (pipeTank == null || checkForPumpCover(cover)) continue; -// } else { -// CoverableView coverable = neighbor.getCapability(GregtechTileCapabilities.CAPABILITY_COVER_HOLDER, -// facing.getOpposite()); -// if (coverable != null) { -// cover = coverable.getCoverAtSide(facing.getOpposite()); -// if (checkForPumpCover(cover)) continue; -// } -// } -// -// FluidStack drainable = pipeTank.drain(maxFluid, false); -// if (drainable == null || drainable.amount <= 0) { -// continue; -// } -// -// int filled = Math.min(fluidHandler.fill(maxFluid, false), drainable.amount); -// -// if (filled > 0) { -// tanks.add(new FluidTransaction(fluidHandler, pipeTank, filled)); -// availableCapacity += filled; -// } -// maxFluid.amount = amount; // Because some mods do actually modify input fluid stack -// } -// -// if (availableCapacity <= 0) -// return; -// -// // How much of this fluid is available for distribution? -// final double maxAmount = Math.min(getCapacityPerTank() / 2, fluid.amount); -// -// // Now distribute -// for (FluidTransaction transaction : tanks) { -// if (availableCapacity > maxAmount) { -// transaction.amount = (int) Math.floor(transaction.amount * maxAmount / availableCapacity); // Distribute -// // fluids -// // based on -// // percentage -// // available -// // space at -// // destination -// } -// if (transaction.amount == 0) { -// if (tank.getFluidAmount() <= 0) break; // If there is no more stored fluid, stop transferring to prevent -// // dupes -// transaction.amount = 1; // If the percent is not enough to give at least 1L, try to give 1L -// } else if (transaction.amount < 0) { -// continue; -// } -// -// FluidStack toInsert = fluid.copy(); -// toInsert.amount = transaction.amount; -// -// int inserted = transaction.target.fill(toInsert, true); -// if (inserted > 0) { -// transaction.pipeTank.drain(inserted, true); -// } -// } -// } + // private void distributeFluid(int channel, FluidTank tank, FluidStack fluid) { + // // Tank, From, Amount to receive + // List tanks = new ArrayList<>(); + // int amount = fluid.amount; + // + // FluidStack maxFluid = fluid.copy(); + // double availableCapacity = 0; + // + // for (byte i = 0, j = (byte) GTValues.RNG.nextInt(6); i < 6; i++) { + // // Get a list of tanks accepting fluids, and what side they're on + // byte side = (byte) ((i + j) % 6); + // EnumFacing facing = EnumFacing.VALUES[side]; + // + // if (!isConnected(facing) || (lastReceivedFrom & (1 << side)) != 0) { + // continue; + // } + // + // TileEntity neighbor = getNeighbor(facing); + // if (neighbor == null) continue; + // IFluidHandler fluidHandler = neighbor.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, + // facing.getOpposite()); + // if (fluidHandler == null) continue; + // + // IFluidHandler pipeTank = tank; + // Cover cover = getCoverableImplementation().getCoverAtSide(facing); + // + // // pipeTank should only be determined by the cover attached to the actual pipe + // if (cover != null) { + // pipeTank = cover.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, pipeTank); + // // Shutter covers return null capability when active, so check here to prevent NPE + // if (pipeTank == null || checkForPumpCover(cover)) continue; + // } else { + // CoverableView coverable = neighbor.getCapability(GregtechTileCapabilities.CAPABILITY_COVER_HOLDER, + // facing.getOpposite()); + // if (coverable != null) { + // cover = coverable.getCoverAtSide(facing.getOpposite()); + // if (checkForPumpCover(cover)) continue; + // } + // } + // + // FluidStack drainable = pipeTank.drain(maxFluid, false); + // if (drainable == null || drainable.amount <= 0) { + // continue; + // } + // + // int filled = Math.min(fluidHandler.fill(maxFluid, false), drainable.amount); + // + // if (filled > 0) { + // tanks.add(new FluidTransaction(fluidHandler, pipeTank, filled)); + // availableCapacity += filled; + // } + // maxFluid.amount = amount; // Because some mods do actually modify input fluid stack + // } + // + // if (availableCapacity <= 0) + // return; + // + // // How much of this fluid is available for distribution? + // final double maxAmount = Math.min(getCapacityPerTank() / 2, fluid.amount); + // + // // Now distribute + // for (FluidTransaction transaction : tanks) { + // if (availableCapacity > maxAmount) { + // transaction.amount = (int) Math.floor(transaction.amount * maxAmount / availableCapacity); // Distribute + // // fluids + // // based on + // // percentage + // // available + // // space at + // // destination + // } + // if (transaction.amount == 0) { + // if (tank.getFluidAmount() <= 0) break; // If there is no more stored fluid, stop transferring to prevent + // // dupes + // transaction.amount = 1; // If the percent is not enough to give at least 1L, try to give 1L + // } else if (transaction.amount < 0) { + // continue; + // } + // + // FluidStack toInsert = fluid.copy(); + // toInsert.amount = transaction.amount; + // + // int inserted = transaction.target.fill(toInsert, true); + // if (inserted > 0) { + // transaction.pipeTank.drain(inserted, true); + // } + // } + // } -// private boolean checkForPumpCover(@Nullable Cover cover) { -// if (cover instanceof CoverPump coverPump) { -// int pipeThroughput = getNodeData().getThroughput() * 20; -// if (coverPump.getTransferRate() > pipeThroughput) { -// coverPump.setTransferRate(pipeThroughput); -// } -// return coverPump.getManualImportExportMode() == ManualImportExportMode.DISABLED; -// } -// return false; -// } -// -// private IFluidHandler getFluidHandlerAt(EnumFacing facing, EnumFacing oppositeSide) { -// TileEntity tile = world.getTileEntity(pos.offset(facing)); -// if (tile == null) { -// return null; -// } -// return tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, oppositeSide); -// } + // private boolean checkForPumpCover(@Nullable Cover cover) { + // if (cover instanceof CoverPump coverPump) { + // int pipeThroughput = getNodeData().getThroughput() * 20; + // if (coverPump.getTransferRate() > pipeThroughput) { + // coverPump.setTransferRate(pipeThroughput); + // } + // return coverPump.getManualImportExportMode() == ManualImportExportMode.DISABLED; + // } + // return false; + // } + // + // private IFluidHandler getFluidHandlerAt(EnumFacing facing, EnumFacing oppositeSide) { + // TileEntity tile = world.getTileEntity(pos.offset(facing)); + // if (tile == null) { + // return null; + // } + // return tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, oppositeSide); + // } }