implemented stack requesting mechanism, for #1973

This commit is contained in:
SpaceToad 2014-08-14 18:58:17 +02:00
parent 2c7617b126
commit 221a4416e5
26 changed files with 624 additions and 224 deletions

View file

@ -16,7 +16,6 @@ import net.minecraft.world.World;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.core.IZone;
import buildcraft.core.robots.RobotRegistry;
public abstract class EntityRobotBase extends EntityLiving implements IInventory {
@ -62,7 +61,7 @@ public abstract class EntityRobotBase extends EntityLiving implements IInventory
public abstract long getRobotId();
public abstract RobotRegistry getRegistry();
public abstract IRobotRegistry getRegistry();
public abstract void releaseResources();
}

View file

@ -0,0 +1,38 @@
/**
* 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.api.robots;
import net.minecraft.item.ItemStack;
public interface IRequestProvider {
/**
* Return the total number of request slots available from this provider.
*/
int getNumberOfRequests();
/**
* Return the stack requested in slot i, provided that this request is not
* in process of being provided by a robot.
*/
StackRequest getAvailableRequest(int i);
/**
* Allocate the request at slot i to the robot given in parameter, and
* return true if the allocation is successful.
*/
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);
}

View file

@ -0,0 +1,59 @@
/**
* 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.api.robots;
import java.util.Collection;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.core.robots.DockingStation;
import buildcraft.core.robots.ResourceId;
public interface IRobotRegistry {
long getNextRobotId();
void registerRobot(EntityRobotBase robot);
void killRobot(EntityRobotBase robot);
EntityRobotBase getLoadedRobot(long id);
boolean isTaken(ResourceId resourceId);
long robotIdTaking(ResourceId resourceId);
EntityRobotBase robotTaking(ResourceId resourceId);
boolean take(ResourceId resourceId, EntityRobotBase robot);
boolean take(ResourceId resourceId, long robotId);
void release(ResourceId resourceId);
void releaseResources(EntityRobotBase robot);
DockingStation getStation(int x, int y, int z, ForgeDirection side);
Collection<DockingStation> getStations();
void registerStation(DockingStation station);
void removeStation(DockingStation station);
void take(DockingStation station, long robotId);
void release(DockingStation station, long robotId);
void writeToNBT(NBTTagCompound nbt);
void readFromNBT(NBTTagCompound nbt);
}

View file

@ -0,0 +1,18 @@
/**
* 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.api.robots;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
public class StackRequest {
public ItemStack stack;
public int index;
public TileEntity requester;
}

View file

@ -66,6 +66,7 @@ gate.action.station.provide_items=Provide Items
gate.action.station.request_items=Request Items
gate.action.station.drop_items_in_pipe=Drop Items In Pipe
gate.action.station.craft=Craft
gate.action.station.provide_machine_request=Provide Computed Items
gate.action.robot.work_in_area=Work in Area
gate.action.robot.wakeup=Wake Up
gate.action.station.forbid_robot=Robot Forbidden

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

View file

@ -37,6 +37,7 @@ import buildcraft.api.transport.PipeWire;
import buildcraft.builders.schematics.SchematicRotateMeta;
import buildcraft.commander.BlockRequester;
import buildcraft.commander.BlockZonePlan;
import buildcraft.commander.TileRequester;
import buildcraft.commander.TileZonePlan;
import buildcraft.core.DefaultProps;
import buildcraft.core.InterModComms;
@ -90,6 +91,7 @@ import buildcraft.silicon.statements.ActionRobotWorkInArea;
import buildcraft.silicon.statements.ActionStationForbidRobot;
import buildcraft.silicon.statements.ActionStationProvideItems;
import buildcraft.silicon.statements.ActionStationRequestItemsInv;
import buildcraft.silicon.statements.ActionStationRequestItemsMachine;
import buildcraft.silicon.statements.ActionStationRequestItemsPipe;
import buildcraft.silicon.statements.RobotsActionProvider;
import buildcraft.silicon.statements.RobotsTriggerProvider;
@ -129,6 +131,7 @@ public class BuildCraftSilicon extends BuildCraftMod {
public static IAction actionStationProvideItems = new ActionStationProvideItems();
public static IAction actionStationForbidRobot = new ActionStationForbidRobot();
public static IAction actionStationDropInPipe = new ActionStationRequestItemsPipe();
public static IAction actionStationMachineRequestItems = new ActionStationRequestItemsMachine();
public static TechnoSimpleItem technoRedstoneBoard = new TechnoSimpleItem();
public static TechnoSimpleItem technoLaserBlock = new TechnoSimpleItem();
@ -231,6 +234,7 @@ public class BuildCraftSilicon extends BuildCraftMod {
CoreProxy.proxy.registerTileEntity(TileAdvancedCraftingTable.class, "net.minecraft.src.buildcraft.factory.TileAssemblyAdvancedWorkbench");
CoreProxy.proxy.registerTileEntity(TileIntegrationTable.class, "net.minecraft.src.buildcraft.factory.TileIntegrationTable");
CoreProxy.proxy.registerTileEntity(TileZonePlan.class, "net.minecraft.src.buildcraft.commander.TileZonePlan");
CoreProxy.proxy.registerTileEntity(TileRequester.class, "net.minecraft.src.buildcraft.commander.TileRequester");
SchematicRegistry.registerSchematicBlock(laserBlock, SchematicRotateMeta.class, new int[]{2, 5, 3, 4}, true);

View file

@ -29,8 +29,8 @@ import buildcraft.core.utils.Utils;
public class BlockRequester extends BlockBuildCraft {
private IIcon blockTextureDefault;
private IIcon blockTextureSide;
private IIcon blockTextureFront;
public BlockRequester() {
super(Material.iron);
@ -65,21 +65,17 @@ public class BlockRequester extends BlockBuildCraft {
@Override
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister par1IconRegister) {
blockTextureSide = par1IconRegister.registerIcon("buildcraft:commander_side");
blockTextureFront = par1IconRegister.registerIcon("buildcraft:requester_front");
blockTextureDefault = par1IconRegister.registerIcon("buildcraft:commander_side");
blockTextureSide = par1IconRegister.registerIcon("buildcraft:requester_side");
}
@Override
public IIcon getIcon(int i, int j) {
if (j == 0 && i == 3) {
return blockTextureFront;
if (i == 0 || i == 1) {
return blockTextureDefault;
} else {
return blockTextureSide;
}
if (i == j) {
return blockTextureFront;
}
return blockTextureSide;
}
}

View file

@ -11,13 +11,20 @@ package buildcraft.commander;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
public class ContainerRequester extends BuildCraftContainer {
public GuiRequester gui;
public ItemStack[] requests = new ItemStack[TileRequester.NB_ITEMS];
private TileRequester requester;
public ContainerRequester(IInventory playerInventory, TileRequester iRequester) {
@ -47,4 +54,24 @@ public class ContainerRequester extends BuildCraftContainer {
public boolean canInteractWith(EntityPlayer player) {
return true;
}
public void getRequestList() {
RPCHandler.rpcServer(this, "rpcGetRequestList");
}
@RPC(RPCSide.SERVER)
public void rpcGetRequestList(RPCMessageInfo info) {
ItemStack[] stacks = new ItemStack[TileRequester.NB_ITEMS];
for (int i = 0; i < TileRequester.NB_ITEMS; ++i) {
stacks[i] = requester.getRequest(i);
}
RPCHandler.rpcPlayer(info.sender, this, "rpcReceiveRequestList", stacks, null);
}
@RPC(RPCSide.CLIENT)
public void rpcReceiveRequestList(ItemStack[] items, Object dummy) {
requests = items;
}
}

View file

@ -28,18 +28,32 @@ public class GuiRequester extends GuiAdvancedInterface {
private static class RequestSlot extends AdvancedSlot {
private ItemStack item;
private int index;
public RequestSlot(GuiAdvancedInterface gui, int x, int y) {
public RequestSlot(GuiAdvancedInterface gui, int iIndex, int x, int y) {
super(gui, x, y);
index = iIndex;
}
public void setItem(ItemStack itemStack) {
item = itemStack.copy();
TileRequester requester = ((GuiRequester) gui).requester;
if (itemStack != null) {
item = itemStack.copy();
} else {
item = null;
}
requester.setRequest(index, itemStack);
((GuiRequester) gui).getContainer().getRequestList();
}
@Override
public ItemStack getItemStack() {
return item;
ContainerRequester requester = ((GuiRequester) gui).getContainer();
return requester.requests[index];
}
}
@ -47,6 +61,7 @@ public class GuiRequester extends GuiAdvancedInterface {
super(new ContainerRequester(iPlayerInventory, iRequester), iPlayerInventory, TEXTURE);
getContainer().gui = this;
getContainer().getRequestList();
xSize = 256;
ySize = 220;
@ -56,8 +71,7 @@ public class GuiRequester extends GuiAdvancedInterface {
for (int x = 0; x < 4; ++x) {
for (int y = 0; y < 5; ++y) {
slots.add(new RequestSlot(this, 9 + 18 * x, 7 + 18 * y));
slots.add(new RequestSlot(this, x * 5 + y, 9 + 18 * x, 7 + 18 * y));
}
}
}

View file

@ -1,48 +0,0 @@
/**
* 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.commander;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.WorldBlockIndex;
public class StackRequest {
public static final int NULL_LIFETIME = 20 * 60;
public WorldBlockIndex holder;
public int indexInHolder;
public ItemStack stack;
public long requestDate;
public long loadDate;
public boolean fulfilled;
/**
* when loading from NBT, this field may be null. The requested is supposed
* to notify the requester upon loading. If fail to do so for more than
* NULL_LIFETIME cycles, then the request is forgotten
*/
public Entity requester;
public void saveToNBT(NBTTagCompound nbt) {
NBTTagCompound index = new NBTTagCompound();
holder.writeTo(index);
nbt.setTag("index", index);
nbt.setInteger("indexInHolder", indexInHolder);
}
public void loadFromNBT(NBTTagCompound nbt) {
holder = new WorldBlockIndex(nbt.getCompoundTag("index"));
indexInHolder = nbt.getInteger("indexInHolder");
}
}

View file

@ -8,58 +8,51 @@
*/
package buildcraft.commander;
import java.util.ArrayList;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.WorldBlockIndex;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.robots.ResourceIdRequest;
import buildcraft.core.robots.RobotRegistry;
public class TileRequester extends TileBuildCraft implements IInventory {
public class TileRequester extends TileBuildCraft implements IInventory, IRequestProvider {
public static final int NB_ITEMS = 20;
private SimpleInventory inv = new SimpleInventory(NB_ITEMS, "items", 64);
private ArrayList<StackRequest> requirements = new ArrayList<StackRequest>();
private SimpleInventory requests = new SimpleInventory(NB_ITEMS, "requests", 64);
public TileRequester() {
for (int i = 0; i < NB_ITEMS; ++i) {
requirements.add(null);
}
}
public boolean addRequest(ItemStack stack, Entity from) {
for (int i = 0; i < NB_ITEMS; ++i) {
if (requirements.get(i) == null) {
StackRequest r = new StackRequest();
r.fulfilled = false;
r.holder = new WorldBlockIndex(worldObj, xCoord, yCoord, zCoord);
r.indexInHolder = i;
r.loadDate = worldObj.getTotalWorldTime();
r.requestDate = worldObj.getTotalWorldTime();
r.requester = from;
r.stack = stack;
requirements.set(i, r);
return true;
}
@RPC(RPCSide.SERVER)
public void setRequest(int index, ItemStack stack) {
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "setRequest", index, stack);
return;
}
return false;
requests.setInventorySlotContents(index, stack);
}
public ItemStack getRequest(int index) {
return requests.getStackInSlot(index);
}
@Override
public int getSizeInventory() {
return inv.getInventoryStackLimit();
return inv.getSizeInventory();
}
@Override
@ -114,11 +107,9 @@ public class TileRequester extends TileBuildCraft implements IInventory {
@Override
public boolean isItemValidForSlot(int i, ItemStack itemStack) {
StackRequest req = requirements.get(i);
if (req == null) {
if (requests.getStackInSlot(i) == null) {
return false;
} else if (!StackHelper.isMatchingItem(req.stack, itemStack)) {
} else if (!StackHelper.isMatchingItem(requests.getStackInSlot(i), itemStack)) {
return false;
} else {
return inv.isItemValidForSlot(i, itemStack);
@ -132,15 +123,103 @@ public class TileRequester extends TileBuildCraft implements IInventory {
NBTTagCompound invNBT = new NBTTagCompound();
inv.writeToNBT(invNBT);
nbt.setTag("inv", invNBT);
NBTTagCompound reqNBT = new NBTTagCompound();
requests.writeToNBT(reqNBT);
nbt.setTag("req", reqNBT);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
System.out.println("READ");
inv.readFromNBT(nbt.getCompoundTag("inv"));
requests.readFromNBT(nbt.getCompoundTag("req"));
}
public boolean isFulfilled(int i) {
if (requests.getStackInSlot(i) == null) {
return true;
} else if (inv.getStackInSlot(i) == null) {
return false;
} else {
return StackHelper.isMatchingItem(requests.getStackInSlot(i), inv.getStackInSlot(i))
&& inv.getStackInSlot(i).stackSize >= requests.getStackInSlot(i).stackSize;
}
}
@Override
public int getNumberOfRequests() {
return NB_ITEMS;
}
@Override
public StackRequest getAvailableRequest(int i) {
if (requests.getStackInSlot(i) == null) {
return null;
} else if (isFulfilled(i)) {
return null;
} else if (RobotRegistry.getRegistry(worldObj).isTaken(new ResourceIdRequest(this, i))) {
return null;
} else {
StackRequest r = new StackRequest();
r.index = i;
r.stack = requests.getStackInSlot(i);
r.requester = this;
return r;
}
}
@Override
public boolean takeRequest(int i, EntityRobotBase robot) {
if (requests.getStackInSlot(i) == null) {
return false;
} else if (isFulfilled(i)) {
return false;
} else {
return RobotRegistry.getRegistry(worldObj).take(new ResourceIdRequest(this, i), robot);
}
}
@Override
public ItemStack provideItemsForRequest(int i, ItemStack stack) {
ItemStack existingStack = inv.getStackInSlot(i);
if (requests.getStackInSlot(i) == null) {
return stack;
} else if (existingStack == null) {
int maxQty = requests.getStackInSlot(i).stackSize;
if (stack.stackSize <= maxQty) {
inv.setInventorySlotContents(i, stack);
return null;
} else {
ItemStack newStack = stack.copy();
newStack.stackSize = maxQty;
stack.stackSize -= maxQty;
inv.setInventorySlotContents(i, newStack);
return stack;
}
} else if (!StackHelper.isMatchingItem(stack, existingStack)) {
return stack;
} else if (existingStack == null || StackHelper.isMatchingItem(stack, requests.getStackInSlot(i))) {
int maxQty = requests.getStackInSlot(i).stackSize;
if (existingStack.stackSize + stack.stackSize <= maxQty) {
existingStack.stackSize += stack.stackSize;
return null;
} else {
stack.stackSize -= maxQty - existingStack.stackSize;
existingStack.stackSize = maxQty;
return stack;
}
} else {
return stack;
}
}
}

View file

@ -79,7 +79,7 @@ public final class InvUtils {
/**
* Attempts to move a single item from one inventory to another.
*
*
* @param source
* @param dest
* @param filter
@ -259,4 +259,14 @@ public final class InvUtils {
}
return inv;
}
public static IInvSlot getItem(IInventory inv, IStackFilter filter) {
for (IInvSlot s : InventoryIterator.getIterable(inv)) {
if (s.getStackInSlot() != null && filter.matches(s.getStackInSlot())) {
return s;
}
}
return null;
}
}

View file

@ -9,7 +9,6 @@
package buildcraft.core.network;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
@ -90,13 +89,7 @@ public final class RPCHandler {
mapping.mappings = new ClassSerializer[mapping.parameters.length];
for (int j = 0; j < mapping.parameters.length; ++j) {
if (int.class.equals(mapping.parameters[j])) {
// accepted
} else if (char.class.equals(mapping.parameters[j])) {
// accepted
} else if (float.class.equals(mapping.parameters[j])) {
// accepted
} else if (mapping.parameters [j].equals(RPCMessageInfo.class)) {
if (mapping.parameters[j].equals(RPCMessageInfo.class)) {
mapping.hasInfo = true;
} else {
mapping.mappings [j] = ClassMapping.get(mapping.parameters [j]);
@ -332,26 +325,6 @@ public final class RPCHandler {
data.writeBoolean((Boolean) actual);
} else if (String.class.equals(formal)) {
Utils.writeUTF(data, (String) actual);
} else if (formal.isArray()) {
if (formal.getComponentType() == byte.class) {
byte[] array = (byte[]) actual;
data.writeInt(array.length);
data.writeBytes(array);
} else if (formal.getComponentType() == int.class) {
int[] array = (int[]) actual;
data.writeInt(array.length);
for (int element : array) {
data.writeInt(element);
}
} else {
Object[] array = (Object[]) actual;
Class<?> componentType = formal.getComponentType();
data.writeInt(array.length);
for (Object element : array) {
writePrimitive(data, componentType, element);
}
}
} else {
return false;
}
@ -409,29 +382,6 @@ public final class RPCHandler {
actuals[i] = data.readBoolean();
} else if (String.class.equals(formal)) {
actuals[i] = Utils.readUTF(data);
} else if (formal.isArray()) {
final int size = data.readInt();
if (formal.getComponentType() == byte.class) {
byte[] array = new byte[size];
data.readBytes(array);
actuals[i] = array;
} else if (formal.getComponentType() == int.class) {
int[] array = new int[size];
for (int ind = 0; ind < size; ++ind) {
array[ind] = data.readInt();
}
actuals[i] = array;
} else {
Class<?> componentType = formal.getComponentType();
Object[] a = (Object[]) Array.newInstance(componentType, size);
for (int z = 0; z < size; z++) {
readPrimitive(data, componentType, a, z);
}
actuals[i] = a;
}
} else {
return false;
}

View file

@ -94,6 +94,7 @@ public class ClassMapping extends ClassSerializer {
Double,
Short,
Int,
Char,
Boolean,
Enum,
Object
@ -124,6 +125,8 @@ public class ClassMapping extends ClassSerializer {
cptType = CptType.Int;
} else if (boolean.class.equals(cptClass)) {
cptType = CptType.Byte;
} else if (char.class.equals(cptClass)) {
cptType = CptType.Char;
} else if (Enum.class.isAssignableFrom(cptClass)) {
cptType = CptType.Enum;
} else {
@ -157,6 +160,8 @@ public class ClassMapping extends ClassSerializer {
floatFields.add(f);
} else if (double.class.equals(fieldClass)) {
doubleFields.add(f);
} else if (char.class.equals(fieldClass)) {
doubleFields.add(f);
} else {
FieldObject obj = new FieldObject();
obj.mapping = get (fieldClass);
@ -417,6 +422,16 @@ public class ClassMapping extends ClassSerializer {
break;
}
case Char: {
char[] arr = (char[]) obj;
data.writeInt (arr.length);
for (char element : arr) {
data.writeChar(element);
}
break;
}
case Enum: {
Enum<?>[] arr = (Enum[]) obj;
data.writeInt (arr.length);
@ -553,6 +568,23 @@ public class ClassMapping extends ClassSerializer {
break;
}
case Char: {
char[] arr;
if (obj == null) {
arr = new char[size];
} else {
arr = (char[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readChar();
}
obj = arr;
break;
}
case Enum: {
Enum<?>[] arr;
@ -619,8 +651,10 @@ public class ClassMapping extends ClassSerializer {
mapping = new ClassMapping ();
registerSerializer(clas, mapping);
((ClassMapping) mapping).analyzeClass(clas);
} else {
} else if (classes.containsKey(clas.getCanonicalName())) {
mapping = classes.get(clas.getCanonicalName());
} else {
mapping = null;
}
return mapping;

View file

@ -22,6 +22,7 @@ import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.InventoryCopy;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.StackHelper;
@ -97,7 +98,7 @@ public class AIRobotCraftAssemblyTable extends AIRobotCraftGeneric {
} else {
waitedTime++;
if (getItem(new ArrayStackFilter(expectedResult.crafted)) != null) {
if (InvUtils.getItem(robot, new ArrayStackFilter(expectedResult.crafted)) != null) {
crafted = true;
terminate();
} else if (waitedTime > 120 * 60) {
@ -242,16 +243,6 @@ public class AIRobotCraftAssemblyTable extends AIRobotCraftGeneric {
return null;
}
private IInvSlot getItem(IStackFilter filter) {
for (IInvSlot s : InventoryIterator.getIterable(robot)) {
if (s.getStackInSlot() != null && filter.matches(s.getStackInSlot())) {
return s;
}
}
return null;
}
private class ReqStackFilter implements IStackFilter {
@Override
public boolean matches(ItemStack stack) {

View file

@ -20,7 +20,7 @@ import buildcraft.api.core.IInvSlot;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
@ -58,13 +58,13 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric {
public void update() {
if (furnace != null) {
if (!craftStarted) {
if (furnace.getStackInSlot(FUEL_SLOT) == null && getItem(new FuelFilter()) == null) {
if (furnace.getStackInSlot(FUEL_SLOT) == null && InvUtils.getItem(robot, new FuelFilter()) == null) {
startDelegateAI(new AIRobotGotoStationAndLoad(robot, new FuelFilter(), robot.getZoneToWork()));
return;
}
if (getItem(new ArrayStackFilter(input)) == null) {
if (InvUtils.getItem(robot, new ArrayStackFilter(input)) == null) {
startDelegateAI(new AIRobotGotoStationAndLoad(robot, new ArrayStackFilter(input),
robot.getZoneToWork()));
@ -78,12 +78,12 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric {
}
if (furnace.getStackInSlot(FUEL_SLOT) == null) {
IInvSlot s = getItem(new FuelFilter());
IInvSlot s = InvUtils.getItem(robot, new FuelFilter());
furnace.setInventorySlotContents(FUEL_SLOT, s.decreaseStackInSlot(1));
}
if (furnace.getStackInSlot(INPUT_SLOT) == null) {
IInvSlot s = getItem(new ArrayStackFilter(input));
IInvSlot s = InvUtils.getItem(robot, new ArrayStackFilter(input));
furnace.setInventorySlotContents(INPUT_SLOT, s.decreaseStackInSlot(1));
}
@ -205,15 +205,4 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric {
return null;
}
private IInvSlot getItem(IStackFilter filter) {
for (IInvSlot s : InventoryIterator.getIterable(robot)) {
if (s.getStackInSlot() != null && filter.matches(s.getStackInSlot())) {
return s;
}
}
return null;
}
}

View file

@ -33,9 +33,4 @@ public abstract class AIRobotCraftGeneric extends AIRobot {
return crafted;
}
@Override
public double getEnergyCost() {
return 3;
}
}

View file

@ -226,4 +226,9 @@ public class AIRobotCraftWorkbench extends AIRobotCraftGeneric {
return false;
}
}
@Override
public double getEnergyCost() {
return 3;
}
}

View file

@ -0,0 +1,104 @@
/**
* 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.robots;
import net.minecraft.item.ItemStack;
import buildcraft.api.core.BlockIndex;
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.inventory.InvUtils;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.silicon.statements.ActionStationRequestItemsMachine;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
public class AIRobotDeliverRequested extends AIRobot {
private StackRequest requested;
private boolean delivered = false;
public AIRobotDeliverRequested(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotDeliverRequested(EntityRobotBase robot, StackRequest request) {
super(robot);
requested = request;
}
@Override
public void start() {
startDelegateAI(new AIRobotSearchAndGotoStation(robot, new StationProviderFilter(), robot.getZoneToWork()));
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotSearchAndGotoStation) {
if (!ai.success()) {
terminate();
return;
}
IInvSlot slot = InvUtils.getItem(robot, new ArrayStackFilter(requested.stack));
if (slot == null) {
terminate();
return;
}
ItemStack newStack = ((IRequestProvider)
requested.requester).provideItemsForRequest(requested.index,
slot.getStackInSlot().copy());
if (newStack == null || newStack.stackSize != slot.getStackInSlot().stackSize) {
delivered = true;
slot.setStackInSlot(newStack);
}
terminate();
}
}
@Override
public boolean success() {
return delivered;
}
private class StationProviderFilter implements IStationFilter {
@Override
public boolean matches(DockingStation station) {
boolean actionFound = false;
Pipe pipe = station.getPipe().pipe;
if (!station.index().nextTo(new BlockIndex(requested.requester))) {
return false;
}
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationRequestItemsMachine) {
actionFound = true;
}
}
if (!actionFound) {
return false;
}
return true;
}
}
}

View file

@ -9,7 +9,6 @@
package buildcraft.core.robots;
import java.util.Date;
import java.util.LinkedList;
import java.util.WeakHashMap;
import io.netty.buffer.ByteBuf;
@ -46,7 +45,6 @@ import buildcraft.api.mj.MjBattery;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IDockingStation;
import buildcraft.commander.StackRequest;
import buildcraft.core.DefaultProps;
import buildcraft.core.LaserData;
import buildcraft.core.network.RPC;
@ -105,7 +103,6 @@ public class EntityRobot extends EntityRobotBase implements
private WeakHashMap<Entity, Boolean> unreachableEntities = new WeakHashMap<Entity, Boolean>();
private NBTTagList stackRequestNBT;
private LinkedList<StackRequest> stackRequests = new LinkedList<StackRequest>();
@MjBattery
private double mjStored;
@ -442,22 +439,6 @@ public class EntityRobot extends EntityRobotBase implements
nbt.setTag("board", boardNBT);
}
NBTTagList requestsNBT = new NBTTagList();
for (StackRequest r : stackRequests) {
NBTTagCompound cpt = new NBTTagCompound();
NBTTagCompound index = new NBTTagCompound();
r.holder.writeTo(index);
cpt.setTag("index", index);
cpt.setInteger("indexInHolder", r.indexInHolder);
requestsNBT.appendTag(cpt);
}
nbt.setTag("stackRequests", requestsNBT);
nbt.setLong("robotId", robotId);
}

View file

@ -0,0 +1,26 @@
/**
* 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.robots;
import net.minecraft.tileentity.TileEntity;
import buildcraft.api.core.BlockIndex;
public class ResourceIdRequest extends ResourceId {
public ResourceIdRequest() {
}
public ResourceIdRequest(TileEntity tile, int i) {
index = new BlockIndex(tile);
localId = i;
}
}

View file

@ -23,8 +23,9 @@ import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRobotRegistry;
public class RobotRegistry extends WorldSavedData {
public class RobotRegistry extends WorldSavedData implements IRobotRegistry {
public static RobotRegistry[] registries = new RobotRegistry[256];
@ -43,6 +44,7 @@ public class RobotRegistry extends WorldSavedData {
super(id);
}
@Override
public long getNextRobotId() {
long result = nextRobotID;
@ -51,23 +53,26 @@ public class RobotRegistry extends WorldSavedData {
return result;
}
public void registerRobot(EntityRobot robot) {
@Override
public void registerRobot(EntityRobotBase robot) {
markDirty();
if (robot.getRobotId() == EntityRobotBase.NULL_ROBOT_ID) {
robot.setUniqueRobotId(getNextRobotId());
((EntityRobot) robot).setUniqueRobotId(getNextRobotId());
}
robotsLoaded.put(robot.getRobotId(), robot);
robotsLoaded.put(robot.getRobotId(), (EntityRobot) robot);
}
public void killRobot(EntityRobot robot) {
@Override
public void killRobot(EntityRobotBase robot) {
markDirty();
releaseResources(robot, true);
robotsLoaded.remove(robot.getRobotId());
}
@Override
public EntityRobot getLoadedRobot(long id) {
if (robotsLoaded.containsKey(id)) {
return robotsLoaded.get(id);
@ -76,10 +81,12 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public boolean isTaken(ResourceId resourceId) {
return robotIdTaking(resourceId) != EntityRobotBase.NULL_ROBOT_ID;
}
@Override
public long robotIdTaking(ResourceId resourceId) {
if (!resourcesTaken.containsKey(resourceId)) {
return EntityRobotBase.NULL_ROBOT_ID;
@ -97,6 +104,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public EntityRobot robotTaking(ResourceId resourceId) {
long robotId = robotIdTaking(resourceId);
@ -107,12 +115,14 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public boolean take(ResourceId resourceId, EntityRobotBase robot) {
markDirty();
return take(resourceId, robot.getRobotId());
}
@Override
public boolean take(ResourceId resourceId, long robotId) {
if (resourceId == null) {
return false;
@ -137,6 +147,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public void release(ResourceId resourceId) {
if (resourceId == null) {
return;
@ -153,6 +164,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public void releaseResources(EntityRobotBase robot) {
releaseResources(robot, false);
}
@ -195,6 +207,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public DockingStation getStation(int x, int y, int z, ForgeDirection side) {
StationIndex index = new StationIndex(side, x, y, z);
@ -205,10 +218,12 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public Collection<DockingStation> getStations() {
return stations.values();
}
@Override
public void registerStation(DockingStation station) {
markDirty();
@ -221,6 +236,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public void removeStation(DockingStation station) {
markDirty();
@ -235,6 +251,7 @@ public class RobotRegistry extends WorldSavedData {
}
}
@Override
public void take(DockingStation station, long robotId) {
if (!stationsTakenByRobot.containsKey(robotId)) {
stationsTakenByRobot.put(robotId, new HashSet<StationIndex>());
@ -243,6 +260,7 @@ public class RobotRegistry extends WorldSavedData {
stationsTakenByRobot.get(robotId).add(new StationIndex(station));
}
@Override
public void release(DockingStation station, long robotId) {
if (stationsTakenByRobot.containsKey(robotId)) {
stationsTakenByRobot.get(robotId).remove(new StationIndex(station));

View file

@ -18,7 +18,9 @@ import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe;
@ -31,17 +33,24 @@ import buildcraft.api.recipes.IFlexibleRecipe;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IDockingStation;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.recipes.AssemblyRecipeManager;
import buildcraft.core.robots.AIRobotCraftAssemblyTable;
import buildcraft.core.robots.AIRobotCraftFurnace;
import buildcraft.core.robots.AIRobotCraftGeneric;
import buildcraft.core.robots.AIRobotCraftWorkbench;
import buildcraft.core.robots.AIRobotDeliverRequested;
import buildcraft.core.robots.AIRobotGotoSleep;
import buildcraft.core.robots.AIRobotGotoStationToUnload;
import buildcraft.core.robots.AIRobotSearchStation;
import buildcraft.core.robots.AIRobotUnload;
import buildcraft.core.robots.DockingStation;
import buildcraft.core.robots.IStationFilter;
import buildcraft.silicon.statements.ActionRobotCraft;
import buildcraft.silicon.statements.ActionStationRequestItemsMachine;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.ActionSlot;
@ -50,6 +59,7 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
private ItemStack order;
private ArrayList<ItemStack> craftingBlacklist = new ArrayList<ItemStack>();
private HashSet<IDockingStation> reservedStations = new HashSet<IDockingStation>();
private StackRequest currentRequest = null;
public BoardRobotCrafter(EntityRobotBase iRobot) {
super(iRobot);
@ -72,12 +82,14 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
return;
}
order = getCraftingOrder();
robot.releaseResources();
if (currentRequest == null) {
order = getOrderFromHomeStation();
} else {
order = currentRequest.stack;
}
if (order == null) {
craftingBlacklist.clear();
startDelegateAI(new AIRobotGotoSleep(robot));
startDelegateAI(new AIRobotSearchStation(robot, new StationProviderFilter(), robot.getZoneToWork()));
return;
}
@ -109,10 +121,17 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotCraftGeneric) {
if (!ai.success()) {
robot.releaseResources();
currentRequest = null;
craftingBlacklist.add(order);
} else {
// The extra crafted items may make some crafting possible
craftingBlacklist.clear();
if (currentRequest != null) {
startDelegateAI(new AIRobotDeliverRequested(robot, currentRequest));
} else {
robot.releaseResources();
// The extra crafted items may make some crafting possible
craftingBlacklist.clear();
}
}
} else if (ai instanceof AIRobotGotoStationToUnload) {
if (ai.success()) {
@ -120,6 +139,18 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
} else {
startDelegateAI(new AIRobotGotoSleep(robot));
}
} else if (ai instanceof AIRobotSearchStation) {
if (!ai.success()) {
craftingBlacklist.clear();
startDelegateAI(new AIRobotGotoSleep(robot));
} else {
currentRequest = getOrderFromRequestingStation(((AIRobotSearchStation) ai).targetStation, true);
}
} else if (ai instanceof AIRobotDeliverRequested) {
currentRequest = null;
robot.releaseResources();
// The extra crafted items may make some crafting possible
craftingBlacklist.clear();
}
}
@ -176,9 +207,7 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
return false;
}
private ItemStack getCraftingOrder() {
// [1] priority from the current station order
private ItemStack getOrderFromHomeStation() {
DockingStation s = (DockingStation) robot.getLinkedStation();
for (ActionSlot slot : new ActionIterator(s.getPipe().pipe)) {
@ -196,11 +225,56 @@ public class BoardRobotCrafter extends RedstoneBoardRobot {
}
}
// [2] if no order, will look at the "request" stations (either from
// inventories or machines).
// when taking a "request" order, lock the target station
return null;
}
private StackRequest getOrderFromRequestingStation(DockingStation station, boolean take) {
boolean actionFound = false;
Pipe pipe = station.getPipe().pipe;
for (ActionSlot s : new ActionIterator(pipe)) {
if (s.action instanceof ActionStationRequestItemsMachine) {
actionFound = true;
}
}
if (!actionFound) {
return null;
}
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = robot.worldObj.getTileEntity(station.x() + dir.offsetX, station.y()
+ dir.offsetY, station.z()
+ dir.offsetZ);
if (nearbyTile instanceof IRequestProvider) {
IRequestProvider provider = (IRequestProvider) nearbyTile;
for (int i = 0; i < provider.getNumberOfRequests(); ++i) {
StackRequest request = provider.getAvailableRequest(i);
if (request != null && !isBlacklisted(request.stack)) {
if (take) {
if (provider.takeRequest(i, robot)) {
return request;
}
} else {
return request;
}
}
}
}
}
return null;
}
private class StationProviderFilter implements IStationFilter {
@Override
public boolean matches(DockingStation station) {
return getOrderFromRequestingStation(station, false) != null;
}
}
}

View file

@ -0,0 +1,31 @@
/**
* 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.silicon.statements;
import net.minecraft.client.renderer.texture.IIconRegister;
import buildcraft.core.triggers.BCActionPassive;
import buildcraft.core.utils.StringUtils;
public class ActionStationRequestItemsMachine extends BCActionPassive {
public ActionStationRequestItemsMachine() {
super("buildcraft:station.provide_machine_request");
}
@Override
public String getDescription() {
return StringUtils.localize("gate.action.station.provide_machine_request");
}
@Override
public void registerIcons(IIconRegister iconRegister) {
icon = iconRegister.registerIcon("buildcraft:triggers/action_station_machine_request");
}
}

View file

@ -21,6 +21,7 @@ import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.gates.IAction;
import buildcraft.api.gates.IActionProvider;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.transport.IPipeTile;
import buildcraft.core.robots.DockingStation;
import buildcraft.core.robots.boards.BoardRobotCrafter;
@ -57,14 +58,18 @@ public class RobotsActionProvider implements IActionProvider {
}
}
if (((TileGenericPipe) pipe).pipe.transport instanceof PipeTransportItems) {
result.add(BuildCraftSilicon.actionStationDropInPipe);
}
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if (((TileGenericPipe) pipe).getTile(dir) instanceof IInventory) {
result.add(BuildCraftSilicon.actionStationProvideItems);
result.add(BuildCraftSilicon.actionStationRequestItems);
}
if (((TileGenericPipe) pipe).pipe.transport instanceof PipeTransportItems) {
result.add(BuildCraftSilicon.actionStationDropInPipe);
if (((TileGenericPipe) pipe).getTile(dir) instanceof IRequestProvider) {
result.add(BuildCraftSilicon.actionStationMachineRequestItems);
}
}