rewrite the robot's request system, fixes #2853

This commit is contained in:
Hea3veN 2015-07-13 22:57:32 -03:00 committed by Adrian
parent 7a9e0e484d
commit e2a0a7eab4
15 changed files with 435 additions and 230 deletions

View file

@ -10,28 +10,37 @@ package buildcraft.api.robots;
import net.minecraft.item.ItemStack;
/**
* Provide requests of items that need to be fulfilled.
*
* Requests are organized as an linear array, where null entries mark slots
* without a requests. A request in a slot, or the amount of slots, is allowed
* to change before a call to {@link #offerItem(int, ItemStack)}, but it is not
* recommended that this is frequent, since the request delivery won't fail
* until it is offered the previous request.
*/
public interface IRequestProvider {
/**
* Return the total number of request slots available from this provider.
*
* @return
*/
int getNumberOfRequests();
int getRequestsCount();
/**
* Return the stack requested in slot i, provided that this request is not
* in process of being provided by a robot.
* Return a stack with the request in the slot.
*
* @param slot
* @return the request in the slot, or null if there's no request.
*/
StackRequest getAvailableRequest(int i);
ItemStack getRequest(int slot);
/**
* Allocate the request at slot i to the robot given in parameter, and
* return true if the allocation is successful.
* Fulfill the request in slot with the stack given and return any excess.
*
* @param slot
* @param stack
* @return any excess that was not used to fulfill the request.
*/
boolean takeRequest(int i, EntityRobotBase robot);
/**
* Provide a stack to fulfill request at index i. Return the stack minus
* items that have been taken.
*/
ItemStack provideItemsForRequest(int i, ItemStack stack);
ItemStack offerItem(int slot, ItemStack stack);
}

View file

@ -9,50 +9,17 @@
package buildcraft.api.robots;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.BlockIndex;
public abstract class ResourceId {
public BlockIndex index = new BlockIndex();
public ForgeDirection side = ForgeDirection.UNKNOWN;
public int localId = 0;
protected ResourceId() {
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
ResourceId compareId = (ResourceId) obj;
return index.equals(compareId.index)
&& side == compareId.side
&& localId == compareId.localId;
}
@Override
public int hashCode() {
return (((index != null ? index.hashCode() : 0) * 37) + (side != null ? side.ordinal() : 0) * 37) + localId;
}
public void writeToNBT(NBTTagCompound nbt) {
NBTTagCompound indexNBT = new NBTTagCompound();
index.writeTo(indexNBT);
nbt.setTag("index", indexNBT);
nbt.setByte("side", (byte) side.ordinal());
nbt.setInteger("localId", localId);
nbt.setString("resourceName", RobotManager.getResourceIdName(getClass()));
}
protected void readFromNBT(NBTTagCompound nbt) {
index = new BlockIndex(nbt.getCompoundTag("index"));
side = ForgeDirection.values()[nbt.getByte("side")];
localId = nbt.getInteger("localId");
}
public static ResourceId load(NBTTagCompound nbt) {
@ -75,12 +42,4 @@ public abstract class ResourceId {
return null;
}
public void taken(long robotId) {
}
public void released(long robotId) {
}
}

View file

@ -8,12 +8,20 @@
*/
package buildcraft.api.robots;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.BlockIndex;
public class ResourceIdBlock extends ResourceId {
public BlockIndex index = new BlockIndex();
public ForgeDirection side = ForgeDirection.UNKNOWN;
public ResourceIdBlock() {
}
@ -30,4 +38,35 @@ public class ResourceIdBlock extends ResourceId {
index = new BlockIndex(tile);
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
ResourceIdBlock compareId = (ResourceIdBlock) obj;
return index.equals(compareId.index) && side == compareId.side;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(index.hashCode()).append(side != null ? side.ordinal() : 0).build();
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
NBTTagCompound indexNBT = new NBTTagCompound();
index.writeTo(indexNBT);
nbt.setTag("index", indexNBT);
nbt.setByte("side", (byte) side.ordinal());
}
@Override
protected void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
index = new BlockIndex(nbt.getCompoundTag("index"));
side = ForgeDirection.values()[nbt.getByte("side")];
}
}

View file

@ -8,19 +8,57 @@
*/
package buildcraft.api.robots;
import net.minecraft.tileentity.TileEntity;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.BlockIndex;
public class ResourceIdRequest extends ResourceId {
public ResourceIdRequest() {
private BlockIndex index;
private ForgeDirection side;
private int slot;
public ResourceIdRequest(DockingStation station, int slot) {
index = station.index();
side = station.side();
this.slot = slot;
}
public ResourceIdRequest(TileEntity tile, int i) {
index = new BlockIndex(tile);
localId = i;
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
ResourceIdRequest compareId = (ResourceIdRequest) obj;
return index.equals(compareId.index) && side.equals(compareId.side) && slot == compareId.slot;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(index.hashCode()).append(side.hashCode()).append(slot).build();
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
NBTTagCompound indexNBT = new NBTTagCompound();
index.writeTo(indexNBT);
nbt.setTag("index", indexNBT);
nbt.setByte("side", (byte) side.ordinal());
nbt.setInteger("localId", slot);
}
@Override
protected void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
index = new BlockIndex(nbt.getCompoundTag("index"));
side = ForgeDirection.getOrientation(nbt.getByte("side"));
slot = nbt.getInteger("localId");
}
}

View file

@ -1,19 +0,0 @@
/**
* Copyright (c) 2011-2015, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* The BuildCraft API is distributed under the terms of the MIT License.
* Please check the contents of the license, which should be located
* as "LICENSE.API" in the BuildCraft source code distribution.
*/
package buildcraft.api.robots;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
public class StackRequest {
public ItemStack stack;
public int index;
public TileEntity requester;
public DockingStation station;
}

View file

@ -23,7 +23,9 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.WorldSettings.GameType;
import cpw.mods.fml.relauncher.Side;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
@ -32,18 +34,13 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftBuilders;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.BCLog;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.core.IPathProvider;
import buildcraft.api.core.Position;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.ResourceIdRequest;
import buildcraft.api.robots.RobotManager;
import buildcraft.api.robots.StackRequest;
import buildcraft.api.tiles.IControllable;
import buildcraft.api.tiles.IHasWork;
import buildcraft.builders.blueprints.RecursiveBlueprintBuilder;
@ -837,7 +834,7 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
}
@Override
public int getNumberOfRequests() {
public int getRequestsCount() {
if (currentBuilder == null) {
return 0;
} else if (!(currentBuilder instanceof BptBuilderBlueprint)) {
@ -850,7 +847,7 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
}
@Override
public StackRequest getAvailableRequest(int i) {
public ItemStack getRequest(int slot) {
if (currentBuilder == null) {
return null;
} else if (!(currentBuilder instanceof BptBuilderBlueprint)) {
@ -858,41 +855,25 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
} else {
BptBuilderBlueprint bpt = (BptBuilderBlueprint) currentBuilder;
if (bpt.neededItems.size() <= i) {
if (bpt.neededItems.size() <= slot) {
return null;
}
RequirementItemStack requirement = bpt.neededItems.get(i);
RequirementItemStack requirement = bpt.neededItems.get(slot);
int qty = quantityMissing(requirement.stack, requirement.size);
if (qty <= 0) {
return null;
}
StackRequest request = new StackRequest();
request.index = i;
request.requester = this;
request.stack = requirement.stack;
return request;
ItemStack requestStack = requirement.stack.copy();
requestStack.stackSize = qty;
return requestStack;
}
}
@Override
public boolean takeRequest(int i, EntityRobotBase robot) {
if (currentBuilder == null) {
return false;
} else if (!(currentBuilder instanceof BptBuilderBlueprint)) {
return false;
} else {
return RobotManager.registryProvider.getRegistry(worldObj).take(new ResourceIdRequest(this, i), robot);
}
}
@Override
public ItemStack provideItemsForRequest(int i, ItemStack stack) {
public ItemStack offerItem(int slot, ItemStack stack) {
if (currentBuilder == null) {
return stack;
} else if (!(currentBuilder instanceof BptBuilderBlueprint)) {
@ -900,11 +881,11 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
} else {
BptBuilderBlueprint bpt = (BptBuilderBlueprint) currentBuilder;
if (bpt.neededItems.size() <= i) {
if (bpt.neededItems.size() <= slot) {
return stack;
}
RequirementItemStack requirement = bpt.neededItems.get(i);
RequirementItemStack requirement = bpt.neededItems.get(slot);
int qty = quantityMissing(requirement.stack, requirement.size);

View file

@ -1,17 +1,23 @@
package buildcraft.robotics;
import java.util.List;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftRobotics;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.EnumColor;
import buildcraft.api.gates.IGate;
import buildcraft.api.robots.DockingStation;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.RobotManager;
import buildcraft.api.statements.IStatement;
import buildcraft.api.statements.StatementSlot;
import buildcraft.api.transport.IInjectable;
import buildcraft.api.transport.IPipeTile;
@ -22,7 +28,7 @@ import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.pipes.PipeFluidsWood;
import buildcraft.transport.pipes.PipeItemsWood;
public class DockingStationPipe extends DockingStation {
public class DockingStationPipe extends DockingStation implements IRequestProvider {
private IInjectable injectablePipe = new IInjectable() {
@Override
@ -158,7 +164,7 @@ public class DockingStationPipe extends DockingStation {
return (IRequestProvider) nearbyTile;
}
}
return null;
return this;
}
@Override
@ -199,4 +205,62 @@ public class DockingStationPipe extends DockingStation {
public void onChunkUnload() {
pipe = null;
}
@Override
public int getRequestsCount() {
return 127;
}
@Override
public ItemStack getRequest(int slot) {
ForgeDirection side = ForgeDirection.getOrientation((slot & 0x70) >> 4);
int action = (slot & 0xc) >> 2;
int param = slot & 0x3;
IGate gate = getPipe().getPipe().getGate(side);
if (gate == null) {
return null;
}
List<IStatement> actions = gate.getActions();
if (actions.size() <= action) {
return null;
}
if (actions.get(action) != BuildCraftRobotics.actionStationRequestItems) {
return null;
}
List<StatementSlot> activeActions = gate.getActiveActions();
StatementSlot slotStmt = null;
for (StatementSlot stmt : activeActions) {
if (stmt.statement == actions.get(action)) {
slotStmt = stmt;
break;
}
}
if (slotStmt == null) {
return null;
}
if (slotStmt.parameters.length <= param) {
return null;
}
if (slotStmt.parameters[param] == null) {
return null;
}
return slotStmt.parameters[param].getItemStack();
}
@Override
public ItemStack offerItem(int slot, ItemStack stack) {
int consumed = injectablePipe.injectItem(stack, true, side.getOpposite(), null);
if (stack.stackSize > consumed) {
ItemStack newStack = stack.copy();
newStack.stackSize -= consumed;
return newStack;
}
return null;
}
}

View file

@ -20,7 +20,9 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.LongHashMap;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.world.ChunkEvent;
@ -174,8 +176,6 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry {
getResourcesTakenByRobot(robotId).add(resourceId);
resourceId.taken(robotId);
return true;
} else {
return false;
@ -195,7 +195,6 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry {
getResourcesTakenByRobot(robotId).remove(resourceId);
resourcesTaken.remove(resourceId);
resourceId.released(robotId);
}
}

View file

@ -0,0 +1,108 @@
/**
* Copyright (c) 2011-2015, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* The BuildCraft API is distributed under the terms of the MIT License.
* Please check the contents of the license, which should be located
* as "LICENSE.API" in the BuildCraft source code distribution.
*/
package buildcraft.robotics;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.robots.DockingStation;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.IRobotRegistry;
import buildcraft.api.robots.ResourceId;
import buildcraft.api.robots.ResourceIdRequest;
import buildcraft.api.robots.RobotManager;
public class StackRequest {
private IRequestProvider requester;
private int slot;
private ItemStack stack;
private DockingStation station;
private BlockIndex stationIndex;
private ForgeDirection stationSide;
public StackRequest(IRequestProvider requester, int slot, ItemStack stack) {
this.requester = requester;
this.slot = slot;
this.stack = stack;
this.station = null;
}
private StackRequest(int slot, ItemStack stack, BlockIndex stationIndex, ForgeDirection stationSide) {
requester = null;
this.slot = slot;
this.stack = stack;
station = null;
this.stationIndex = stationIndex;
this.stationSide = stationSide;
}
public IRequestProvider getRequester(World world) {
if (requester == null) {
requester = getStation(world).getRequestProvider();
}
return requester;
}
public int getSlot() {
return slot;
}
public ItemStack getStack() {
return stack;
}
public DockingStation getStation(World world) {
if (station == null) {
IRobotRegistry robotRegistry = RobotManager.registryProvider.getRegistry(world);
station = robotRegistry.getStation(stationIndex.x, stationIndex.y, stationIndex.z, stationSide);
}
return station;
}
public void setStation(DockingStation station) {
this.station = station;
this.stationIndex = station.index();
this.stationSide = station.side();
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setInteger("slot", slot);
NBTTagCompound stackNBT = new NBTTagCompound();
stack.writeToNBT(stackNBT);
nbt.setTag("stack", stackNBT);
NBTTagCompound stationIndexNBT = new NBTTagCompound();
station.index().writeTo(stationIndexNBT);
nbt.setTag("stationIndex", stationIndexNBT);
nbt.setByte("stationSide", (byte) station.side().ordinal());
}
public static StackRequest loadFromNBT(NBTTagCompound nbt) {
int slot = nbt.getInteger("slot");
ItemStack stack = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("stack"));
BlockIndex stationIndex = new BlockIndex(nbt.getCompoundTag("stationIndex"));
ForgeDirection stationSide = ForgeDirection.values()[nbt.getByte("stationSide")];
return new StackRequest(slot, stack, stationIndex, stationSide);
}
public ResourceId getResourceId(World world) {
return new ResourceIdRequest(getStation(world), slot);
}
}

View file

@ -14,14 +14,11 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.ResourceIdRequest;
import buildcraft.api.robots.RobotManager;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.lib.block.TileBuildCraft;
import buildcraft.core.lib.inventory.SimpleInventory;
import buildcraft.core.lib.inventory.StackHelper;
@ -60,7 +57,7 @@ public class TileRequester extends TileBuildCraft implements IInventory, IReques
}
}
public ItemStack getRequest(int index) {
public ItemStack getRequestTemplate(int index) {
return requests.getStackInSlot(index);
}
@ -163,47 +160,48 @@ public class TileRequester extends TileBuildCraft implements IInventory, IReques
}
@Override
public int getNumberOfRequests() {
public int getRequestsCount() {
return NB_ITEMS;
}
@Override
public StackRequest getAvailableRequest(int i) {
public ItemStack getRequest(int i) {
if (requests.getStackInSlot(i) == null) {
return null;
} else if (isFulfilled(i)) {
return null;
} else if (RobotManager.registryProvider.getRegistry(worldObj).isTaken(new ResourceIdRequest(this, i))) {
return null;
} else {
StackRequest r = new StackRequest();
ItemStack request = requests.getStackInSlot(i).copy();
r.index = i;
r.stack = requests.getStackInSlot(i);
r.requester = this;
ItemStack existingStack = inv.getStackInSlot(i);
if (existingStack == null) {
return request;
}
return r;
if (!StackHelper.isMatchingItemOrList(request, existingStack)) {
return null;
}
request.stackSize -= existingStack.stackSize;
if (request.stackSize <= 0) {
return null;
}
return request;
}
}
@Override
public boolean takeRequest(int i, EntityRobotBase robot) {
if (requests.getStackInSlot(i) == null) {
return false;
} else if (isFulfilled(i)) {
return false;
} else {
return RobotManager.registryProvider.getRegistry(worldObj).take(new ResourceIdRequest(this, i), robot);
}
}
@Override
public ItemStack provideItemsForRequest(int i, ItemStack stack) {
public ItemStack offerItem(int i, ItemStack stack) {
ItemStack existingStack = inv.getStackInSlot(i);
if (requests.getStackInSlot(i) == null) {
return stack;
} else if (existingStack == null) {
if (!StackHelper.isMatchingItemOrList(stack, requests.getStackInSlot(i))) {
return stack;
}
int maxQty = requests.getStackInSlot(i).stackSize;
if (stack.stackSize <= maxQty) {
@ -221,7 +219,7 @@ public class TileRequester extends TileBuildCraft implements IInventory, IReques
}
} else if (!StackHelper.isMatchingItemOrList(stack, existingStack)) {
return stack;
} else if (existingStack == null || StackHelper.isMatchingItemOrList(stack, requests.getStackInSlot(i))) {
} else if (StackHelper.isMatchingItemOrList(stack, requests.getStackInSlot(i))) {
int maxQty = requests.getStackInSlot(i).stackSize;
if (existingStack.stackSize + stack.stackSize <= maxQty) {

View file

@ -9,14 +9,15 @@
package buildcraft.robotics.ai;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.lib.inventory.InvUtils;
import buildcraft.core.lib.inventory.filters.ArrayStackOrListFilter;
import buildcraft.robotics.StackRequest;
public class AIRobotDeliverRequested extends AIRobot {
@ -35,48 +36,67 @@ public class AIRobotDeliverRequested extends AIRobot {
@Override
public void start() {
startDelegateAI(new AIRobotGotoStation(robot, requested.station));
startDelegateAI(new AIRobotGotoStation(robot, requested.getStation(robot.worldObj)));
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotGotoStation) {
if (!ai.success()) {
setSuccess(false);
terminate();
return;
}
IInvSlot slot = InvUtils.getItem(robot, new ArrayStackOrListFilter(requested.stack));
IInvSlot slot = InvUtils.getItem(robot, new ArrayStackOrListFilter(requested.getStack()));
if (slot == null) {
setSuccess(false);
terminate();
return;
}
if (requested.requester != null) {
ItemStack newStack = ((IRequestProvider)
requested.requester).provideItemsForRequest(requested.index,
slot.getStackInSlot().copy());
if (newStack == null || newStack.stackSize != slot.getStackInSlot().stackSize) {
delivered = true;
slot.setStackInSlot(newStack);
}
IRequestProvider requester = requested.getRequester(robot.worldObj);
if (requester == null) {
setSuccess(false);
terminate();
} else {
startDelegateAI(new AIRobotUnload(robot));
return;
}
} else if (ai instanceof AIRobotUnload) {
delivered = ai.success();
ItemStack newStack = requester.offerItem(requested.getSlot(), slot.getStackInSlot().copy());
if (newStack == null || newStack.stackSize != slot.getStackInSlot().stackSize) {
slot.setStackInSlot(newStack);
}
terminate();
}
}
@Override
public boolean success() {
return delivered;
}
@Override
public boolean canLoadFromNBT() {
return true;
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (requested != null) {
NBTTagCompound requestNBT = new NBTTagCompound();
requested.writeToNBT(requestNBT);
nbt.setTag("currentRequest", requestNBT);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("currentRequest")) {
requested = StackRequest.loadFromNBT(nbt.getCompoundTag("currentRequest"));
}
}
}

View file

@ -8,7 +8,9 @@
*/
package buildcraft.robotics.ai;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.minecraft.item.ItemStack;
@ -16,20 +18,15 @@ import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.DockingStation;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.StackRequest;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.api.statements.StatementParameterItemStack;
import buildcraft.api.statements.StatementSlot;
import buildcraft.core.lib.inventory.StackHelper;
import buildcraft.core.lib.inventory.filters.IStackFilter;
import buildcraft.robotics.IStationFilter;
import buildcraft.robotics.statements.ActionRobotFilter;
import buildcraft.robotics.statements.ActionStationRequestItems;
import buildcraft.robotics.statements.ActionStationRequestItemsMachine;
import buildcraft.robotics.StackRequest;
public class AIRobotSearchStackRequest extends AIRobot {
public StackRequest request = null;
public DockingStation station = null;
private Collection<ItemStack> blackList;
@ -57,11 +54,13 @@ public class AIRobotSearchStackRequest extends AIRobot {
if (!ai.success()) {
terminate();
} else {
request = getOrderFromRequestingAction(((AIRobotSearchStation) ai).targetStation);
if (request == null) {
request = getOrderFromRequestingStation(((AIRobotSearchStation) ai).targetStation, true);
}
// request =
// getOrderFromRequestingAction(((AIRobotSearchStation)
// ai).targetStation);
//
// if (request == null) {
request = getOrderFromRequestingStation(((AIRobotSearchStation) ai).targetStation, true);
// }
terminate();
}
@ -84,29 +83,16 @@ public class AIRobotSearchStackRequest extends AIRobot {
}
private StackRequest getOrderFromRequestingStation(DockingStation station, boolean take) {
if (!ActionRobotFilter.canInteractWithItem(station, filter, ActionStationRequestItemsMachine.class)) {
return null;
}
IRequestProvider provider = station.getRequestProvider();
if (provider == null) {
return null;
}
for (int i = 0; i < provider.getNumberOfRequests(); ++i) {
StackRequest requestFound = provider.getAvailableRequest(i);
if (requestFound != null
&& !isBlacklisted(requestFound.stack)
&& filter.matches(requestFound.stack)) {
requestFound.station = station;
for (StackRequest req : getAvailableRequests(station)) {
if (!isBlacklisted(req.getStack()) && filter.matches(req.getStack())) {
req.setStation(station);
if (take) {
if (provider.takeRequest(i, robot)) {
return requestFound;
if (robot.getRegistry().take(req.getResourceId(robot.worldObj), robot)) {
return req;
}
} else {
return requestFound;
return req;
}
}
}
@ -114,32 +100,32 @@ public class AIRobotSearchStackRequest extends AIRobot {
return null;
}
private StackRequest getOrderFromRequestingAction(DockingStation station) {
for (StatementSlot s : station.getActiveActions()) {
if (s.statement instanceof ActionStationRequestItems) {
for (IStatementParameter p : s.parameters) {
StatementParameterItemStack param = (StatementParameterItemStack) p;
private Collection<StackRequest> getAvailableRequests(DockingStation station) {
List<StackRequest> result = new ArrayList<StackRequest>();
if (param != null && !isBlacklisted(param.getItemStack())) {
StackRequest req = new StackRequest();
req.station = station;
req.stack = param.getItemStack();
return req;
}
}
}
IRequestProvider provider = station.getRequestProvider();
if (provider == null) {
return result;
}
return null;
for (int i = 0; i < provider.getRequestsCount(); i++) {
if (provider.getRequest(i) == null) {
continue;
}
StackRequest req = new StackRequest(provider, i, provider.getRequest(i));
req.setStation(station);
if (!robot.getRegistry().isTaken(req.getResourceId(robot.worldObj))) {
result.add(req);
}
}
return result;
}
private class StationProviderFilter implements IStationFilter {
@Override
public boolean matches(DockingStation station) {
return getOrderFromRequestingAction(station) != null
|| getOrderFromRequestingStation(station, false) != null;
return getOrderFromRequestingStation(station, false) != null;
}
}

View file

@ -9,6 +9,7 @@
package buildcraft.robotics.ai;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.IInvSlot;
@ -19,7 +20,7 @@ import buildcraft.api.transport.IInjectable;
import buildcraft.core.lib.inventory.InventoryIterator;
import buildcraft.core.lib.inventory.filters.ArrayStackOrListFilter;
import buildcraft.robotics.statements.ActionRobotFilter;
import buildcraft.robotics.statements.ActionStationInputItems;
import buildcraft.robotics.statements.ActionStationAcceptItems;
public class AIRobotUnload extends AIRobot {
@ -65,7 +66,7 @@ public class AIRobotUnload extends AIRobot {
if (!ActionRobotFilter
.canInteractWithItem(station, new ArrayStackOrListFilter(robotSlot.getStackInSlot()),
ActionStationInputItems.class)) {
ActionStationAcceptItems.class)) {
return false;
}

View file

@ -11,14 +11,15 @@ package buildcraft.robotics.boards;
import java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.lib.inventory.StackHelper;
import buildcraft.core.lib.inventory.filters.IStackFilter;
import buildcraft.robotics.StackRequest;
import buildcraft.robotics.ai.AIRobotDeliverRequested;
import buildcraft.robotics.ai.AIRobotDisposeItems;
import buildcraft.robotics.ai.AIRobotGotoSleep;
@ -44,9 +45,6 @@ public class BoardRobotDelivery extends RedstoneBoardRobot {
@Override
public void update() {
if (robot.containsItems()) {
// Always makes sure that when starting a craft, the inventory is
// clean.
startDelegateAI(new AIRobotDisposeItems(robot));
return;
}
@ -55,7 +53,12 @@ public class BoardRobotDelivery extends RedstoneBoardRobot {
startDelegateAI(new AIRobotSearchStackRequest(robot, ActionRobotFilter.getGateFilter(robot
.getLinkedStation()), deliveryBlacklist));
} else {
startDelegateAI(new AIRobotGotoStationAndLoad(robot, new ReqFilter(), 1));
startDelegateAI(new AIRobotGotoStationAndLoad(robot, new IStackFilter() {
@Override
public boolean matches(ItemStack stack) {
return currentRequest != null && StackHelper.isMatchingItemOrList(stack, currentRequest.getStack());
}
}, currentRequest.getStack().stackSize));
}
}
@ -68,32 +71,51 @@ public class BoardRobotDelivery extends RedstoneBoardRobot {
} else {
currentRequest = ((AIRobotSearchStackRequest) ai).request;
if (!currentRequest.station.take(robot)) {
currentRequest = null;
if (!currentRequest.getStation(robot.worldObj).take(robot)) {
releaseCurrentRequest();
}
}
} else if (ai instanceof AIRobotGotoStationAndLoad) {
if (!ai.success()) {
deliveryBlacklist.add(currentRequest.stack);
robot.releaseResources();
currentRequest = null;
deliveryBlacklist.add(currentRequest.getStack());
releaseCurrentRequest();
} else {
startDelegateAI(new AIRobotDeliverRequested(robot, currentRequest));
}
} else if (ai instanceof AIRobotDeliverRequested) {
robot.releaseResources();
releaseCurrentRequest();
}
}
private void releaseCurrentRequest() {
if (currentRequest != null) {
robot.getRegistry().release(currentRequest.getResourceId(robot.worldObj));
currentRequest.getStation(robot.worldObj).release(robot);
currentRequest = null;
}
}
private class ReqFilter implements IStackFilter {
@Override
public boolean matches(ItemStack stack) {
if (currentRequest == null) {
return false;
} else {
return StackHelper.isMatchingItemOrList(stack, currentRequest.stack);
}
@Override
public boolean canLoadFromNBT() {
return true;
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (currentRequest != null) {
NBTTagCompound requestNBT = new NBTTagCompound();
currentRequest.writeToNBT(requestNBT);
nbt.setTag("currentRequest", requestNBT);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("currentRequest")) {
currentRequest = StackRequest.loadFromNBT(nbt.getCompoundTag("currentRequest"));
}
}
}

View file

@ -70,7 +70,7 @@ public class ContainerRequester extends BuildCraftContainer implements ICommandR
final ItemStack[] stacks = new ItemStack[TileRequester.NB_ITEMS];
for (int i = 0; i < TileRequester.NB_ITEMS; ++i) {
stacks[i] = requester.getRequest(i);
stacks[i] = requester.getRequestTemplate(i);
}
BuildCraftCore.instance.sendToPlayer((EntityPlayer) sender, new PacketCommand(this, "receiveRequestList",