rewrite the robot's request system, fixes #2853
This commit is contained in:
parent
6dad865f5f
commit
a5cdd8c4b1
16 changed files with 438 additions and 232 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -15,4 +15,7 @@ Improvements:
|
|||
* Fluid pipe capacity and extraction rate now scales with the base flow multiplier. (asie)
|
||||
* Debugger support for fluid pipes (asie)
|
||||
* Add events for robot interaction and removal (asie)
|
||||
|
||||
* Rewritten robots request system (hea3ven)
|
||||
- Changed the IRequestProvider api to be independent of robots.
|
||||
- Carrier robots can now carry more than an item at a time.
|
||||
- Builders and requesters now request more than one item at a time.
|
||||
|
|
|
@ -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;
|
||||
|
@ -839,7 +836,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)) {
|
||||
|
@ -852,7 +849,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)) {
|
||||
|
@ -860,41 +857,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)) {
|
||||
|
@ -902,11 +883,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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,15 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
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;
|
||||
|
@ -175,8 +176,6 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry {
|
|||
|
||||
getResourcesTakenByRobot(robotId).add(resourceId);
|
||||
|
||||
resourceId.taken(robotId);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -196,7 +195,6 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry {
|
|||
|
||||
getResourcesTakenByRobot(robotId).remove(resourceId);
|
||||
resourcesTaken.remove(resourceId);
|
||||
resourceId.released(robotId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
108
common/buildcraft/robotics/StackRequest.java
Executable file
108
common/buildcraft/robotics/StackRequest.java
Executable 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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,33 +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 canLoadFromNBT() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ItemStack stack) {
|
||||
if (currentRequest == null) {
|
||||
return false;
|
||||
} else {
|
||||
return StackHelper.isMatchingItemOrList(stack, currentRequest.stack);
|
||||
}
|
||||
@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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue