Skip to content

Commit

Permalink
Merge pull request #27 from GTNewHorizons/feature/ender-conduit-round…
Browse files Browse the repository at this point in the history
…-robin

Add round-robin button to ender conduit
  • Loading branch information
Dream-Master authored Dec 10, 2020
2 parents e2b41a4 + c7a334c commit 27a0a44
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 35 deletions.
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;
}
}

0 comments on commit 27a0a44

Please sign in to comment.