start filter implementation for fluids, #1985

This commit is contained in:
SpaceToad 2014-08-17 10:21:33 +02:00
parent 2c69299172
commit a38bedf5fe
14 changed files with 225 additions and 128 deletions

View file

@ -0,0 +1,56 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.inventory.filters;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
/**
* Returns true if the stack matches any one one of the filter stacks.
*/
public class ArrayFluidFilter implements IFluidFilter {
protected Fluid[] fluids;
public ArrayFluidFilter(ItemStack... stacks) {
fluids = new Fluid[stacks.length];
for (int i = 0; i < stacks.length; ++i) {
fluids[i] = FluidContainerRegistry.getFluidForFilledItem(stacks[i]).getFluid();
}
}
public ArrayFluidFilter(Fluid... iFluids) {
fluids = iFluids;
}
public boolean hasFilter() {
for (Fluid filter : fluids) {
if (filter != null) {
return true;
}
}
return false;
}
@Override
public boolean matches(Fluid fluid) {
for (Fluid filter : fluids) {
if (filter != null && fluid.getID() == filter.getID()) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,16 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.inventory.filters;
import net.minecraftforge.fluids.Fluid;
public interface IFluidFilter {
boolean matches(Fluid fluid);
}

View file

@ -0,0 +1,23 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.inventory.filters;
import net.minecraftforge.fluids.Fluid;
/**
* Returns true if the stack matches any one one of the filter stacks.
*/
public class PassThroughFluidFilter implements IFluidFilter {
@Override
public boolean matches(Fluid fluid) {
return fluid != null;
}
}

View file

@ -42,6 +42,10 @@ public class AIRobotCraftWorkbench extends AIRobotCraftGeneric {
private ArrayList<ArrayStackFilter> requirements;
private ItemStack output;
public AIRobotCraftWorkbench(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotCraftWorkbench(EntityRobotBase iRobot, IRecipe iRecipe) {
super(iRobot);

View file

@ -11,25 +11,28 @@ package buildcraft.core.robots;
import buildcraft.api.core.IZone;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.IFluidFilter;
public class AIRobotGotoStationAndLoadFluids extends AIRobot {
private boolean found = false;
private IZone zone;
private IFluidFilter filter;
public AIRobotGotoStationAndLoadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotGotoStationAndLoadFluids(EntityRobotBase iRobot, IZone iZone) {
public AIRobotGotoStationAndLoadFluids(EntityRobotBase iRobot, IFluidFilter iFilter, IZone iZone) {
super(iRobot);
zone = iZone;
filter = iFilter;
}
@Override
public void start() {
startDelegateAI(new AIRobotGotoStationToLoadFluids(robot, zone));
startDelegateAI(new AIRobotGotoStationToLoadFluids(robot, filter, zone));
}
@Override
@ -37,7 +40,7 @@ public class AIRobotGotoStationAndLoadFluids extends AIRobot {
if (ai instanceof AIRobotGotoStationToLoadFluids) {
if (ai.success()) {
found = true;
startDelegateAI(new AIRobotLoadFluids(robot));
startDelegateAI(new AIRobotLoadFluids(robot, filter));
} else {
terminate();
}

View file

@ -11,25 +11,28 @@ package buildcraft.core.robots;
import buildcraft.api.core.IZone;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.IFluidFilter;
public class AIRobotGotoStationAndUnloadFluids extends AIRobot {
private boolean found = false;
private IZone zone;
private IFluidFilter filter;
public AIRobotGotoStationAndUnloadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotGotoStationAndUnloadFluids(EntityRobotBase iRobot, IZone iZone) {
public AIRobotGotoStationAndUnloadFluids(EntityRobotBase iRobot, IFluidFilter iFilter, IZone iZone) {
super(iRobot);
zone = iZone;
filter = iFilter;
}
@Override
public void start() {
startDelegateAI(new AIRobotGotoStationToUnloadFluids(robot, zone));
startDelegateAI(new AIRobotGotoStationToUnloadFluids(robot, filter, zone));
}
@Override
@ -37,7 +40,7 @@ public class AIRobotGotoStationAndUnloadFluids extends AIRobot {
if (ai instanceof AIRobotGotoStationToUnloadFluids) {
if (ai.success()) {
found = true;
startDelegateAI(new AIRobotUnloadFluids(robot));
startDelegateAI(new AIRobotUnloadFluids(robot, filter));
} else {
terminate();
}

View file

@ -1,5 +1,5 @@
/**
drainable * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public

View file

@ -17,25 +17,25 @@ import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.core.IZone;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.StatementParameterStackFilter;
import buildcraft.core.inventory.filters.IFluidFilter;
import buildcraft.silicon.statements.ActionRobotFilter;
import buildcraft.silicon.statements.ActionStationProvideFluids;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
public class AIRobotGotoStationToLoadFluids extends AIRobot {
private boolean found = false;
private IZone zone;
private IFluidFilter filter;
public AIRobotGotoStationToLoadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotGotoStationToLoadFluids(EntityRobotBase iRobot, IZone iZone) {
public AIRobotGotoStationToLoadFluids(EntityRobotBase iRobot, IFluidFilter iFiler, IZone iZone) {
super(iRobot);
zone = iZone;
filter = iFiler;
}
@Override
@ -61,25 +61,7 @@ public class AIRobotGotoStationToLoadFluids extends AIRobot {
@Override
public boolean matches(DockingStation station) {
boolean actionFound = false;
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationProvideFluids) {
StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters);
/*
* if (!param.hasFilter() || param.matches(filter)) {
* actionFound = true; break; }
*/
actionFound = true;
break;
}
}
if (!actionFound) {
if (!ActionRobotFilter.canInteractWithFluid(station, filter, ActionStationProvideFluids.class)) {
return false;
}
@ -92,7 +74,12 @@ public class AIRobotGotoStationToLoadFluids extends AIRobot {
IFluidHandler handler = (IFluidHandler) nearbyTile;
FluidStack drainable = handler.drain(station.side, 1, false);
if (robot.canFill(ForgeDirection.UNKNOWN, drainable.getFluid())) {
// TODO: there is no account taken for the filter on the
// gate here. See LoadFluid, GotoStationToLoad and Load for
// items as well.
if (drainable != null
&& filter.matches(drainable.getFluid())
&& robot.canFill(ForgeDirection.UNKNOWN, drainable.getFluid())) {
return true;
}
}

View file

@ -17,25 +17,25 @@ import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.core.IZone;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.StatementParameterStackFilter;
import buildcraft.core.inventory.filters.IFluidFilter;
import buildcraft.silicon.statements.ActionRobotFilter;
import buildcraft.silicon.statements.ActionStationAcceptFluids;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
public class AIRobotGotoStationToUnloadFluids extends AIRobot {
private boolean found = false;
private IZone zone;
private IFluidFilter filter;
public AIRobotGotoStationToUnloadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotGotoStationToUnloadFluids(EntityRobotBase iRobot, IZone iZone) {
public AIRobotGotoStationToUnloadFluids(EntityRobotBase iRobot, IFluidFilter iFilter, IZone iZone) {
super(iRobot);
zone = iZone;
filter = iFilter;
}
@Override
@ -61,25 +61,7 @@ public class AIRobotGotoStationToUnloadFluids extends AIRobot {
@Override
public boolean matches(DockingStation station) {
boolean actionFound = false;
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationAcceptFluids) {
StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters);
/*
* if (!param.hasFilter() || param.matches(filter)) {
* actionFound = true; break; }
*/
actionFound = true;
break;
}
}
if (!actionFound) {
if (!ActionRobotFilter.canInteractWithFluid(station, filter, ActionStationAcceptFluids.class)) {
return false;
}
@ -93,7 +75,9 @@ public class AIRobotGotoStationToUnloadFluids extends AIRobot {
FluidStack drainable = robot.drain(ForgeDirection.UNKNOWN, 1, false);
if (handler.canFill(station.side, drainable.getFluid())) {
int filledAmount = handler.fill(station.side, drainable, false);
if (filledAmount > 0) {
return true;
}
}

View file

@ -17,24 +17,24 @@ import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.core.inventory.filters.StatementParameterStackFilter;
import buildcraft.core.inventory.filters.IFluidFilter;
import buildcraft.silicon.statements.ActionRobotFilter;
import buildcraft.silicon.statements.ActionStationProvideFluids;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
public class AIRobotLoadFluids extends AIRobot {
private int loaded = 0;
private int waitedCycles = 0;
private IFluidFilter filter;
public AIRobotLoadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotLoadFluids(EntityRobotBase iRobot, IStackFilter iFilter) {
public AIRobotLoadFluids(EntityRobotBase iRobot, IFluidFilter iFilter) {
super(iRobot);
filter = iFilter;
}
@Override
@ -55,27 +55,9 @@ public class AIRobotLoadFluids extends AIRobot {
private void doLoad() {
if (robot.getDockingStation() != null) {
boolean actionFound = false;
DockingStation station = (DockingStation) robot.getDockingStation();
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationProvideFluids) {
StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters);
/*
* if (!param.hasFilter() || param.matches(filter)) {
* actionFound = true; break; }
*/
actionFound = true;
break;
}
}
if (!actionFound) {
if (!ActionRobotFilter.canInteractWithFluid(station, filter, ActionStationProvideFluids.class)) {
return;
}
@ -86,16 +68,21 @@ public class AIRobotLoadFluids extends AIRobot {
if (nearbyTile != null && nearbyTile instanceof IFluidHandler) {
IFluidHandler handler = (IFluidHandler) nearbyTile;
FluidStack drainable = handler.drain(station.side, FluidContainerRegistry.BUCKET_VOLUME, false)
.copy();
FluidStack drainable = handler.drain(station.side, FluidContainerRegistry.BUCKET_VOLUME, false);
int filled = robot.fill(ForgeDirection.UNKNOWN, drainable, true);
if (drainable != null
&& filter.matches(drainable.getFluid())) {
if (filled > 0) {
drainable.amount = filled;
handler.drain(station.side, drainable, true);
loaded += filled;
return;
drainable = drainable.copy();
int filled = robot.fill(ForgeDirection.UNKNOWN, drainable, true);
if (filled > 0) {
drainable.amount = filled;
handler.drain(station.side, drainable, true);
loaded += filled;
return;
}
}
}
}

View file

@ -17,24 +17,24 @@ import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.core.inventory.filters.StatementParameterStackFilter;
import buildcraft.core.inventory.filters.IFluidFilter;
import buildcraft.silicon.statements.ActionRobotFilter;
import buildcraft.silicon.statements.ActionStationAcceptFluids;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
public class AIRobotUnloadFluids extends AIRobot {
private int unloaded = 0;
private int waitedCycles = 0;
private IFluidFilter filter;
public AIRobotUnloadFluids(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotUnloadFluids(EntityRobotBase iRobot, IStackFilter iFilter) {
public AIRobotUnloadFluids(EntityRobotBase iRobot, IFluidFilter iFilter) {
super(iRobot);
filter = iFilter;
}
@Override
@ -55,27 +55,9 @@ public class AIRobotUnloadFluids extends AIRobot {
private void doLoad() {
if (robot.getDockingStation() != null) {
boolean actionFound = false;
DockingStation station = (DockingStation) robot.getDockingStation();
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationAcceptFluids) {
StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters);
/*
* if (!param.hasFilter() || param.matches(filter)) {
* actionFound = true; break; }
*/
actionFound = true;
break;
}
}
if (!actionFound) {
if (!ActionRobotFilter.canInteractWithFluid(station, filter, ActionStationAcceptFluids.class)) {
return;
}
@ -90,19 +72,17 @@ public class AIRobotUnloadFluids extends AIRobot {
FluidStack drainable = robot.drain(ForgeDirection.UNKNOWN, FluidContainerRegistry.BUCKET_VOLUME,
false);
if (drainable == null) {
return;
}
if (drainable != null && filter.matches(drainable.getFluid())) {
drainable = drainable.copy();
drainable = drainable.copy();
int filled = handler.fill(station.side, drainable, true);
int filled = handler.fill(station.side, drainable, true);
if (filled > 0) {
drainable.amount = filled;
robot.drain(ForgeDirection.UNKNOWN, drainable, true);
unloaded += filled;
return;
if (filled > 0) {
drainable.amount = filled;
robot.drain(ForgeDirection.UNKNOWN, drainable, true);
unloaded += filled;
return;
}
}
}
}

View file

@ -15,6 +15,7 @@ import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.robots.AIRobotGotoSleep;
import buildcraft.core.robots.AIRobotGotoStationAndLoadFluids;
import buildcraft.core.robots.AIRobotGotoStationAndUnloadFluids;
import buildcraft.silicon.statements.ActionRobotFilter;
public class BoardRobotFluidCarrier extends RedstoneBoardRobot {
@ -29,13 +30,15 @@ public class BoardRobotFluidCarrier extends RedstoneBoardRobot {
@Override
public void update() {
startDelegateAI(new AIRobotGotoStationAndLoadFluids(robot, robot.getZoneToWork()));
startDelegateAI(new AIRobotGotoStationAndLoadFluids(robot, ActionRobotFilter.getGateFluidFilter(robot
.getLinkedStation()), robot.getZoneToWork()));
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotGotoStationAndLoadFluids) {
startDelegateAI(new AIRobotGotoStationAndUnloadFluids(robot, robot.getZoneToWork()));
startDelegateAI(new AIRobotGotoStationAndUnloadFluids(robot, ActionRobotFilter.getGateFluidFilter(robot
.getLinkedStation()), robot.getZoneToWork()));
} else if (ai instanceof AIRobotGotoStationAndUnloadFluids) {
if (!ai.success()) {
startDelegateAI(new AIRobotGotoSleep(robot));

View file

@ -364,6 +364,9 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
if (resource == null) {
return 0;
}
// Handle coolant
if (IronEngineCoolant.getCoolant(resource) != null) {

View file

@ -14,15 +14,23 @@ import java.util.Collection;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.api.gates.ActionParameterItemStack;
import buildcraft.api.gates.IActionParameter;
import buildcraft.api.robots.IDockingStation;
import buildcraft.core.inventory.filters.ArrayFluidFilter;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.inventory.filters.IFluidFilter;
import buildcraft.core.inventory.filters.IStackFilter;
import buildcraft.core.inventory.filters.PassThroughFluidFilter;
import buildcraft.core.inventory.filters.PassThroughStackFilter;
import buildcraft.core.inventory.filters.StatementParameterStackFilter;
import buildcraft.core.robots.DockingStation;
import buildcraft.core.triggers.BCActionPassive;
import buildcraft.core.utils.StringUtils;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
@ -87,4 +95,44 @@ public class ActionRobotFilter extends BCActionPassive {
return new ArrayStackFilter(stacks.toArray(new ItemStack[stacks.size()]));
}
}
public static IFluidFilter getGateFluidFilter(IDockingStation station) {
Collection<ItemStack> stacks = getGateFilterStacks(station);
if (stacks.size() == 0) {
return new PassThroughFluidFilter();
} else {
return new ArrayFluidFilter(stacks.toArray(new ItemStack[stacks.size()]));
}
}
public static boolean canInteractWithFluid(DockingStation station, IFluidFilter filter, Class<?> actionClass) {
boolean actionFound = false;
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (actionClass.isAssignableFrom(s.action.getClass())) {
StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters);
if (!param.hasFilter()) {
actionFound = true;
break;
} else {
for (ItemStack stack : param.getStacks()) {
if (stack != null) {
FluidStack fluid = FluidContainerRegistry.getFluidForFilledItem(stack);
if (fluid != null && filter.matches(fluid.getFluid())) {
actionFound = true;
break;
}
}
}
}
}
}
return actionFound;
}
}