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

Add round-robin button to ender conduit #27

Merged
merged 1 commit into from
Dec 10, 2020
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
Expand Up @@ -66,6 +66,7 @@
import crazypants.enderio.conduit.packet.PacketOCConduitSignalColor;
import crazypants.enderio.conduit.packet.PacketRedstoneConduitOutputStrength;
import crazypants.enderio.conduit.packet.PacketRedstoneConduitSignalColor;
import crazypants.enderio.conduit.packet.PacketRoundRobinMode;
import crazypants.enderio.conduit.redstone.IInsulatedRedstoneConduit;
import crazypants.enderio.conduit.redstone.IRedstoneConduit;
import crazypants.enderio.conduit.redstone.InsulatedRedstoneConduit;
Expand Down Expand Up @@ -104,6 +105,7 @@ public static BlockConduitBundle create() {
PacketHandler.INSTANCE.registerMessage(PacketSlotVisibility.class, PacketSlotVisibility.class, PacketHandler.nextID(), Side.SERVER);
PacketHandler.INSTANCE.registerMessage(PacketOCConduitSignalColor.class, PacketOCConduitSignalColor.class,
PacketHandler.nextID(), Side.SERVER);
PacketHandler.INSTANCE.registerMessage(PacketRoundRobinMode.class, PacketRoundRobinMode.class, PacketHandler.nextID(), Side.SERVER);

BlockConduitBundle result = new BlockConduitBundle();
result.init();
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/crazypants/enderio/conduit/gui/LiquidSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.util.Collections;
import java.util.List;

import com.enderio.core.client.gui.button.ToggleButton;
import crazypants.enderio.conduit.packet.PacketRoundRobinMode;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
Expand Down Expand Up @@ -41,11 +43,13 @@ public class LiquidSettings extends BaseSettingsPanel {
static final int ID_REDSTONE_BUTTON = GuiExternalConnection.nextButtonId();

private static final int ID_COLOR_BUTTON = GuiExternalConnection.nextButtonId();
private static final int ID_ROUND_ROBIN_BUTTON = GuiExternalConnection.nextButtonId();
private static final int ID_WHITELIST = GuiExternalConnection.nextButtonId();

private static final int NEXT_FILTER_ID = 989322;

private final RedstoneModeButton rsB;
private final ToggleButton roundRobinB;
private final ColorButton colorB;

private static final String autoExtractStr = EnderIO.lang.localize("gui.conduit.fluid.autoExtract");
Expand Down Expand Up @@ -112,6 +116,16 @@ public RedstoneControlMode getRedstoneControlMode() {
colorB = new ColorButton(gui, ID_COLOR_BUTTON, x, y);
colorB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.redstone.signalColor"));
colorB.setColorIndex(conduit.getExtractionSignalColor(gui.getDir()).ordinal());

if (isEnder) {
x += rsB.getWidth() + gap;
roundRobinB = new ToggleButton(gui, ID_ROUND_ROBIN_BUTTON, x, y, IconEIO.ROUND_ROBIN_OFF, IconEIO.ROUND_ROBIN);
roundRobinB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinEnabled"));
roundRobinB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinDisabled"));
roundRobinB.setPaintSelectedBorder(false);
} else {
roundRobinB = null;
}
}

private void addFilterTooltips() {
Expand All @@ -134,15 +148,27 @@ public void actionPerformed(GuiButton guiButton) {
} else if(guiButton.id == NEXT_FILTER_ID) {
inOutShowIn = !inOutShowIn;
if(isInput()) {
if (isEnder) {
roundRobinB.onGuiInit();
}
rsB.onGuiInit();
colorB.onGuiInit();
} else {
if (isEnder) {
roundRobinB.detach();
}
rsB.detach();
colorB.detach();
}
if(isFilterVisible()) {
updateWhiteListButton(eConduit.getFilter(gui.getDir(), isInput()));
}
} else if(guiButton.id == ID_ROUND_ROBIN_BUTTON) {
if (isEnder && isInput()) {
final boolean selected = roundRobinB.isSelected();
eConduit.setRoundRobin(gui.getDir(), selected);
PacketHandler.INSTANCE.sendToServer(new PacketRoundRobinMode(eConduit, gui.getDir()));
}
}
}

Expand Down Expand Up @@ -209,6 +235,11 @@ private void updateGuiVisibility() {
return;
}

if(isInput()) {
roundRobinB.onGuiInit();
roundRobinB.setSelected(eConduit.isRoundRobin(gui.getDir()));
}

if(isFilterVisible()) {
gui.getContainer().setInventorySlotsVisible(true);
addFilterTooltips();
Expand Down Expand Up @@ -241,6 +272,7 @@ public void deactivate() {
rsB.detach();
colorB.detach();
if(isEnder) {
roundRobinB.detach();
gui.getContainer().setInventorySlotsVisible(false);
if(filterToolTips != null) {
for (GuiToolTip tt : filterToolTips) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package crazypants.enderio.conduit.liquid;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.enderio.core.client.render.IconUtil;
import com.enderio.core.common.util.BlockCoord;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.EnderIO;
import crazypants.enderio.conduit.*;
import crazypants.enderio.conduit.geom.CollidableComponent;
import crazypants.enderio.machine.RedstoneControlMode;
import crazypants.enderio.tool.ToolUtil;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
Expand All @@ -17,20 +20,11 @@
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;

import com.enderio.core.client.render.IconUtil;
import com.enderio.core.common.util.BlockCoord;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.EnderIO;
import crazypants.enderio.conduit.AbstractConduitNetwork;
import crazypants.enderio.conduit.ConduitUtil;
import crazypants.enderio.conduit.ConnectionMode;
import crazypants.enderio.conduit.IConduit;
import crazypants.enderio.conduit.RaytraceResult;
import crazypants.enderio.conduit.geom.CollidableComponent;
import crazypants.enderio.machine.RedstoneControlMode;
import crazypants.enderio.tool.ToolUtil;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class EnderLiquidConduit extends AbstractLiquidConduit {

Expand Down Expand Up @@ -68,7 +62,7 @@ public int getTextureType() {

private final EnumMap<ForgeDirection, FluidFilter> outputFilters = new EnumMap<ForgeDirection, FluidFilter>(ForgeDirection.class);
private final EnumMap<ForgeDirection, FluidFilter> inputFilters = new EnumMap<ForgeDirection, FluidFilter>(ForgeDirection.class);

private int roundRobin = 0;
@Override
public ItemStack createItem() {
return new ItemStack(EnderIO.itemLiquidConduit, 1, 2);
Expand Down Expand Up @@ -302,6 +296,11 @@ public FluidTankInfo[] getTankInfo(ForgeDirection from) {
@Override
protected void readTypeSettings(ForgeDirection dir, NBTTagCompound dataRoot) {
super.readTypeSettings(dir, dataRoot);
if(dataRoot.hasKey("roundRobin")) {
setRoundRobin(dir, dataRoot.getBoolean("roundRobin"));
} else {
setRoundRobin(dir, true);
}
if (dataRoot.hasKey("outputFilters")) {
FluidFilter out = new FluidFilter();
out.readFromNBT(dataRoot.getCompoundTag("outputFilters"));
Expand All @@ -317,6 +316,7 @@ protected void readTypeSettings(ForgeDirection dir, NBTTagCompound dataRoot) {
@Override
protected void writeTypeSettingsToNbt(ForgeDirection dir, NBTTagCompound dataRoot) {
super.writeTypeSettingsToNbt(dir, dataRoot);
dataRoot.setBoolean("roundRobin", isRoundRobin(dir));
FluidFilter out = outputFilters.get(dir);
if (out != null) {
NBTTagCompound outTag = new NBTTagCompound();
Expand All @@ -334,6 +334,7 @@ protected void writeTypeSettingsToNbt(ForgeDirection dir, NBTTagCompound dataRoo
@Override
public void writeToNBT(NBTTagCompound nbtRoot) {
super.writeToNBT(nbtRoot);
nbtRoot.setInteger("roundRobin", roundRobin);
for (Entry<ForgeDirection, FluidFilter> entry : inputFilters.entrySet()) {
if(entry.getValue() != null) {
FluidFilter f = entry.getValue();
Expand All @@ -359,6 +360,11 @@ public void writeToNBT(NBTTagCompound nbtRoot) {
@Override
public void readFromNBT(NBTTagCompound nbtRoot, short nbtVersion) {
super.readFromNBT(nbtRoot, nbtVersion);
if(nbtRoot.hasKey("roundRobin")) {
roundRobin = nbtRoot.getInteger("roundRobin");
} else {
roundRobin = 0b111111;
}
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
String key = "inFilts." + dir.name();
if(nbtRoot.hasKey(key)) {
Expand All @@ -383,4 +389,14 @@ public void readFromNBT(NBTTagCompound nbtRoot, short nbtVersion) {

}

public boolean isRoundRobin(ForgeDirection dir) {
return (roundRobin & dir.flag) != 0;
}

public void setRoundRobin(ForgeDirection dir, boolean roundRobin) {
if (roundRobin)
this.roundRobin |= dir.flag;
else
this.roundRobin &= ~dir.flag;
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,66 @@
package crazypants.enderio.conduit.liquid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;

import com.enderio.core.common.util.BlockCoord;
import com.enderio.core.common.util.RoundRobinIterator;

import crazypants.enderio.conduit.AbstractConduitNetwork;
import crazypants.enderio.conduit.ConnectionMode;
import crazypants.enderio.config.Config;

public class EnderLiquidConduitNetwork extends AbstractConduitNetwork<ILiquidConduit, EnderLiquidConduit> {
private class TankIterator implements Iterator<NetworkTank> {
private int index = -1;
private int currentCount = 0;

public TankIterator start() {
currentCount = 0;
return this;
}

@Override
public boolean hasNext() {
return !tanks.isEmpty() && currentCount < tanks.size();
}

@Override
public NetworkTank next() {
if (tanks.isEmpty()) {
return null;
}
currentCount++;
index++;
if (index >= tanks.size()) {
index = 0;
}
return tanks.get(index);
}

@Override
public void remove() {
}

public void rewind() {
if (index == 0)
index = tanks.size() - 1;
else
index--;
currentCount--;
}
}

public static final int MAX_EXTRACT_PER_TICK = Config.enderFluidConduitExtractRate;
public static final int MAX_IO_PER_TICK = Config.enderFluidConduitMaxIoRate;

List<NetworkTank> tanks = new ArrayList<NetworkTank>();
Map<NetworkTankKey, NetworkTank> tankMap = new HashMap<NetworkTankKey, NetworkTank>();

Map<NetworkTank, RoundRobinIterator<NetworkTank>> iterators;
Map<NetworkTank, TankIterator> iterators;

boolean filling;

Expand Down Expand Up @@ -93,17 +128,21 @@ public int fillFrom(NetworkTank tank, FluidStack resource, boolean doFill) {
int remaining = resource.amount;
//TODO: Only change starting pos of iterator is doFill is true so a false then true returns the same

for (NetworkTank target : getIteratorForTank(tank)) {
if(!target.equals(tank) && target.acceptsOuput && target.isValid() && matchedFilter(resource, target.con, target.conDir, false)) {
TankIterator iterator;
for (iterator = getIteratorForTank(tank).start(); iterator.hasNext(); ) {
NetworkTank target = iterator.next();
if (!target.equals(tank) && target.acceptsOuput && target.isValid() && matchedFilter(resource, target.con, target.conDir, false)) {
int vol = target.externalTank.fill(target.tankDir, resource.copy(), doFill);
remaining -= vol;
filled += vol;
if(remaining <= 0) {
return filled;
if (remaining <= 0) {
break;
}
resource.amount = remaining;
}
}
if (!tank.con.isRoundRobin(tank.conDir))
iterator.rewind();
return filled;

} finally {
Expand All @@ -122,13 +161,13 @@ private boolean matchedFilter(FluidStack drained, EnderLiquidConduit con, ForgeD
return filter.matchesFilter(drained);
}

private Iterable<NetworkTank> getIteratorForTank(NetworkTank tank) {
private TankIterator getIteratorForTank(NetworkTank tank) {
if(iterators == null) {
iterators = new HashMap<NetworkTank, RoundRobinIterator<NetworkTank>>();
iterators = new HashMap<>();
}
RoundRobinIterator<NetworkTank> res = iterators.get(tank);
TankIterator res = iterators.get(tank);
if(res == null) {
res = new RoundRobinIterator<NetworkTank>(tanks);
res = new TankIterator();
iterators.put(tank, res);
}
return res;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package crazypants.enderio.conduit.packet;

import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import crazypants.enderio.conduit.liquid.EnderLiquidConduit;
import crazypants.enderio.conduit.liquid.ILiquidConduit;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.common.util.ForgeDirection;

public class PacketRoundRobinMode extends AbstractConduitPacket<ILiquidConduit> implements IMessageHandler<PacketRoundRobinMode, IMessage> {
private ForgeDirection dir;
private boolean roundRobin;

public PacketRoundRobinMode() {
}

public PacketRoundRobinMode(EnderLiquidConduit eConduit, ForgeDirection dir) {
super(eConduit.getBundle().getEntity(), ConTypeEnum.FLUID);
this.dir = dir;
roundRobin = eConduit.isRoundRobin(dir);
}

@Override
public void toBytes(ByteBuf buf) {
super.toBytes(buf);
buf.writeShort(dir.ordinal());
buf.writeBoolean(roundRobin);
}

@Override
public void fromBytes(ByteBuf buf) {
super.fromBytes(buf);
dir = ForgeDirection.values()[buf.readShort()];
roundRobin = buf.readBoolean();
}

@Override
public IMessage onMessage(PacketRoundRobinMode message, MessageContext ctx) {
final ILiquidConduit conduit = message.getTileCasted(ctx);
if (conduit instanceof EnderLiquidConduit) {
((EnderLiquidConduit) conduit).setRoundRobin(message.dir, message.roundRobin);
message.getWorld(ctx).markBlockForUpdate(message.x, message.y, message.z);
}
return null;
}
}