diff --git a/api/buildcraft/api/core/BlockIndex.java b/api/buildcraft/api/core/BlockIndex.java index 91fb05b4..4a9e40b9 100644 --- a/api/buildcraft/api/core/BlockIndex.java +++ b/api/buildcraft/api/core/BlockIndex.java @@ -50,7 +50,7 @@ public class BlockIndex implements Comparable { } public BlockIndex(TileEntity entity) { - this(entity.xCoord, entity.yCoord, entity.xCoord); + this(entity.xCoord, entity.yCoord, entity.zCoord); } /** diff --git a/api/buildcraft/api/robots/AIRobot.java b/api/buildcraft/api/robots/AIRobot.java index e2101ac3..1a45f639 100755 --- a/api/buildcraft/api/robots/AIRobot.java +++ b/api/buildcraft/api/robots/AIRobot.java @@ -8,20 +8,9 @@ */ package buildcraft.api.robots; -import java.util.HashSet; - import net.minecraft.nbt.NBTTagCompound; -import buildcraft.api.core.BlockIndex; - public class AIRobot { - // TODO: we need a more generic resource handler here, for: - // - blocks taken by robots - // - stations reserved by robots - // - orders taken by robots - // and possibly others. - public static HashSet reservedBlocks = new HashSet(); - public EntityRobotBase robot; private AIRobot delegateAI; @@ -190,32 +179,4 @@ public class AIRobot { return ai; } - - // TODO: we should put the three calls below into one object making sure - // that blocks are released before being assigned again, and which has a - // finalize () method to free potential block upon garbage collection. - public static boolean isFreeBlock(BlockIndex index) { - synchronized (reservedBlocks) { - return !reservedBlocks.contains(index); - } - } - - public static boolean reserveBlock(BlockIndex index) { - synchronized (reservedBlocks) { - if (!reservedBlocks.contains(index)) { - reservedBlocks.add(index); - return true; - } else { - return false; - } - } - } - - public static void releaseBlock(BlockIndex index) { - synchronized (reservedBlocks) { - if (reservedBlocks.contains(index)) { - reservedBlocks.remove(index); - } - } - } } diff --git a/api/buildcraft/api/robots/DockingStationRegistry.java b/api/buildcraft/api/robots/DockingStationRegistry.java deleted file mode 100755 index 3ac17050..00000000 --- a/api/buildcraft/api/robots/DockingStationRegistry.java +++ /dev/null @@ -1,106 +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.api.robots; - -import java.security.InvalidParameterException; -import java.util.Collection; -import java.util.HashMap; - -import net.minecraftforge.common.util.ForgeDirection; - -public final class DockingStationRegistry { - - private static HashMap stations = new HashMap(); - - private DockingStationRegistry() { - - } - - private static class StationIndex { - public int x, y, z; - public ForgeDirection side; - - public StationIndex(int ix, int iy, int iz, ForgeDirection iSide) { - // TODO: should probably consider dimension id here too - x = ix; - y = iy; - z = iz; - side = iSide; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof StationIndex) { - StationIndex d = (StationIndex) obj; - - return d.x == x && d.y == y && d.z == z && d.side == side; - } - - return super.equals(obj); - } - - @Override - public int hashCode() { - return ((x * 37 + y) * 37 + z * 37) + side.ordinal(); - } - - @Override - public String toString() { - return "{" + x + ", " + y + ", " + z + ", " + side + "}"; - } - } - - public static IDockingStation getStation(int x, int y, int z, ForgeDirection side) { - StationIndex index = new StationIndex(x, y, z, side); - - if (stations.containsKey(index)) { - return stations.get(index); - } else { - return null; - } - } - - public static Collection getStations() { - return stations.values(); - } - - public static void registerStation(IDockingStation station) { - StationIndex index = toIndex(station); - - if (stations.containsKey(index)) { - throw new InvalidParameterException("Station " + index + " already registerd"); - } else { - stations.put(index, station); - } - } - - public static void removeStation(IDockingStation station) { - StationIndex index = toIndex(station); - - if (stations.containsKey(index)) { - if (station.linked() != null) { - station.linked().setDead(); - } - - if (station.reserved() != null) { - station.reserved().reserveStation(null); - } - - stations.remove(index); - } - } - - private static StationIndex toIndex(IDockingStation station) { - return new StationIndex(station.x(), station.y(), station.z(), station.side()); - } - - public static void clear() { - stations.clear(); - } -} diff --git a/api/buildcraft/api/robots/EntityRobotBase.java b/api/buildcraft/api/robots/EntityRobotBase.java index b27ff179..025261cd 100755 --- a/api/buildcraft/api/robots/EntityRobotBase.java +++ b/api/buildcraft/api/robots/EntityRobotBase.java @@ -16,11 +16,13 @@ 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 { public static final double MAX_ENERGY = 10000; public static final double SAFETY_ENERGY = MAX_ENERGY / 4; + public static final long NULL_ROBOT_ID = Long.MAX_VALUE; public EntityRobotBase(World par1World) { super(par1World); @@ -34,8 +36,6 @@ public abstract class EntityRobotBase extends EntityLiving implements IInventory public abstract IDockingStation getLinkedStation(); - public abstract IDockingStation getReservedStation(); - public abstract RedstoneBoardRobot getBoard(); public abstract void aimItemAt(int x, int y, int z); @@ -50,16 +50,19 @@ public abstract class EntityRobotBase extends EntityLiving implements IInventory public abstract void undock(); - public abstract boolean reserveStation(IDockingStation station); - - public abstract boolean linkToStation(IDockingStation station); - public abstract IZone getZoneToWork(); public abstract boolean containsItems(); + public abstract boolean hasFreeSlot(); + public abstract void unreachableEntityDetected(Entity entity); public abstract boolean isKnownUnreachable(Entity entity); + public abstract long getRobotId(); + + public abstract RobotRegistry getRegistry(); + + public abstract void releaseResources(); } diff --git a/api/buildcraft/api/robots/IDockingStation.java b/api/buildcraft/api/robots/IDockingStation.java index 98e7c68c..da16f9aa 100755 --- a/api/buildcraft/api/robots/IDockingStation.java +++ b/api/buildcraft/api/robots/IDockingStation.java @@ -12,6 +12,8 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; +import buildcraft.api.core.BlockIndex; + public interface IDockingStation { int x(); @@ -22,11 +24,17 @@ public interface IDockingStation { ForgeDirection side(); - EntityRobotBase reserved(); + EntityRobotBase robotTaking(); - EntityRobotBase linked(); + long robotIdTaking(); + + long linkedId(); + + boolean isTaken(); void writeToNBT(NBTTagCompound nbt); void readFromNBT(NBTTagCompound nbt); + + BlockIndex index(); } diff --git a/common/buildcraft/BuildCraftCore.java b/common/buildcraft/BuildCraftCore.java index 7aa8648a..d7f400e0 100644 --- a/common/buildcraft/BuildCraftCore.java +++ b/common/buildcraft/BuildCraftCore.java @@ -58,7 +58,6 @@ import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.oredict.OreDictionary; import buildcraft.api.blueprints.SchematicRegistry; -import buildcraft.api.boards.RedstoneBoardRobot; import buildcraft.api.core.BCLog; import buildcraft.api.core.BlockIndex; import buildcraft.api.core.BuildCraftAPI; @@ -69,7 +68,6 @@ import buildcraft.api.gates.IAction; import buildcraft.api.gates.ITrigger; import buildcraft.api.gates.StatementManager; import buildcraft.api.recipes.BuildcraftRecipeRegistry; -import buildcraft.api.robots.DockingStationRegistry; import buildcraft.core.BlockSpring; import buildcraft.core.BuildCraftConfiguration; import buildcraft.core.CommandBuildCraft; @@ -677,7 +675,6 @@ public class BuildCraftCore extends BuildCraftMod { @SubscribeEvent public void cleanRegistries(WorldEvent.Unload unload) { - DockingStationRegistry.clear(); BuildCraftAPI.isSoftProperty.clear(); BuildCraftAPI.isWoodProperty.clear(); BuildCraftAPI.isLeavesProperty.clear(); @@ -687,7 +684,6 @@ public class BuildCraftCore extends BuildCraftMod { BuildCraftAPI.isFarmlandProperty.clear(); BuildCraftAPI.isShoveled.clear(); BuildCraftAPI.isDirtProperty.clear(); - RedstoneBoardRobot.reservedBlocks.clear(); } @Mod.EventHandler diff --git a/common/buildcraft/builders/urbanism/TaskBuildSchematic.java b/common/buildcraft/builders/urbanism/TaskBuildSchematic.java deleted file mode 100755 index b1113652..00000000 --- a/common/buildcraft/builders/urbanism/TaskBuildSchematic.java +++ /dev/null @@ -1,60 +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.builders.urbanism; - -import buildcraft.builders.urbanism.TileUrbanist.FrameTask; -import buildcraft.core.blueprints.BuildingSlotBlock; -import buildcraft.core.robots.EntityRobot; -import buildcraft.core.robots.IRobotTask; - -public class TaskBuildSchematic implements IRobotTask { - - BuildingSlotBlock builder; - boolean inBuild = false; - FrameTask task; - - public TaskBuildSchematic (BuildingSlotBlock builder, FrameTask task) { - this.builder = builder; - this.task = task; - } - - @Override - public void setup(EntityRobot robot) { - // robot.setMainAI(new RobotAIMoveAround(robot, builder.x, builder.y, - // builder.z)); - } - - @Override - public void update(EntityRobot robot) { - if (!inBuild && robot.getDistance(builder.x, builder.y, builder.z) <= 15) { - inBuild = true; - robot.setLaserDestination(builder.x, builder.y, builder.z); - robot.showLaser(); - } - - if (inBuild) { - // TODO: need to migrate this to a system based on the new - // blueprints. - /*if (builder.build((IBlueprintBuilderAgent) robot)) { - task.taskDone(); - robot.hideLaser(); - }*/ - } - } - - @Override - public boolean done() { - // TODO: need to migrate this to a system based on the new - // blueprints. - //return builder.isComplete(); - - return true; - } - -} diff --git a/common/buildcraft/builders/urbanism/TileUrbanist.java b/common/buildcraft/builders/urbanism/TileUrbanist.java index e16687bd..498d6567 100755 --- a/common/buildcraft/builders/urbanism/TileUrbanist.java +++ b/common/buildcraft/builders/urbanism/TileUrbanist.java @@ -9,7 +9,6 @@ package buildcraft.builders.urbanism; import java.util.ArrayList; -import java.util.LinkedList; import net.minecraft.client.Minecraft; import net.minecraft.entity.EntityLivingBase; @@ -28,12 +27,8 @@ import buildcraft.core.TileBuildCraft; import buildcraft.core.network.RPC; import buildcraft.core.network.RPCHandler; import buildcraft.core.network.RPCSide; -import buildcraft.core.robots.EntityRobot; -import buildcraft.core.robots.IRobotTask; -import buildcraft.core.robots.IRobotTaskProvider; -import buildcraft.core.robots.RobotTaskProviderRegistry; -public class TileUrbanist extends TileBuildCraft implements IInventory, IRobotTaskProvider, IBoxesProvider { +public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesProvider { public EntityUrbanist urbanist; @@ -48,7 +43,8 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IRobotTa private int p2y = 0; private int p2z = 0; private boolean isCreatingFrame = false; - private LinkedList tasks = new LinkedList(); + + // private LinkedList tasks = new LinkedList(); public void createUrbanistEntity() { if (worldObj.isRemote) { @@ -92,7 +88,7 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IRobotTa @RPC (RPCSide.SERVER) public void eraseBlock (int x, int y, int z) { - tasks.add(new UrbanistTaskErase(this, x, y, z)); + // tasks.add(new UrbanistTaskErase(this, x, y, z)); } public void rpcEraseBlock (int x, int y, int z) { @@ -298,46 +294,9 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IRobotTa } } - @Override - public double getX() { - return xCoord; - } - - @Override - public double getY() { - return yCoord; - } - - @Override - public double getZ() { - return zCoord; - } - - @Override - public boolean isActive() { - return !isInvalid(); - } - - @Override - public IRobotTask getNextTask(EntityRobot robot) { - if (tasks.size() > 0) { - return tasks.getFirst(); - } else { - return null; - } - } - - @Override - public void popNextTask() { - tasks.removeFirst(); - } - - @Override public void initialize () { - if (!worldObj.isRemote) { - RobotTaskProviderRegistry.registerProvider(this); - } + } @Override diff --git a/common/buildcraft/builders/urbanism/UrbanistTask.java b/common/buildcraft/builders/urbanism/UrbanistTask.java deleted file mode 100755 index 2100254f..00000000 --- a/common/buildcraft/builders/urbanism/UrbanistTask.java +++ /dev/null @@ -1,36 +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.builders.urbanism; - -import buildcraft.core.robots.EntityRobot; -import buildcraft.core.robots.IRobotTask; - -public class UrbanistTask implements IRobotTask { - - protected TileUrbanist urbanist; - - public UrbanistTask (TileUrbanist urbanist) { - this.urbanist = urbanist; - } - - @Override - public void setup(EntityRobot robot) { - - } - - @Override - public void update(EntityRobot robot) { - - } - - @Override - public boolean done() { - return true; - } -} diff --git a/common/buildcraft/builders/urbanism/UrbanistTaskErase.java b/common/buildcraft/builders/urbanism/UrbanistTaskErase.java deleted file mode 100755 index 453af620..00000000 --- a/common/buildcraft/builders/urbanism/UrbanistTaskErase.java +++ /dev/null @@ -1,53 +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.builders.urbanism; - -import buildcraft.core.robots.EntityRobot; - -public class UrbanistTaskErase extends UrbanistTask { - - int x, y, z; - boolean isDone = false; - boolean inBreak = false; - - public UrbanistTaskErase (TileUrbanist urbanist, int x, int y, int z) { - super (urbanist); - - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public void setup(EntityRobot robot) { - //robot.setDestinationAround(x, y, z); - } - - @Override - public void update(EntityRobot robot) { - if (!inBreak && robot.getDistance(x, y, z) <= 10) { - inBreak = true; - robot.setLaserDestination(x + 0.5F, y + 0.5F, z + 0.5F); - robot.showLaser(); - } - - if (inBreak) { - //if (robot.breakBlock(x, y, z)) { - // isDone = true; - // robot.hideLaser(); - //} - } - } - - @Override - public boolean done() { - return isDone; - } - -} diff --git a/common/buildcraft/core/ItemRobot.java b/common/buildcraft/core/ItemRobot.java index 518e2d07..0b7c3042 100755 --- a/common/buildcraft/core/ItemRobot.java +++ b/common/buildcraft/core/ItemRobot.java @@ -11,12 +11,17 @@ package buildcraft.core; import java.util.List; import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + import buildcraft.BuildCraftSilicon; import buildcraft.api.boards.RedstoneBoardNBT; import buildcraft.api.boards.RedstoneBoardRegistry; @@ -27,7 +32,7 @@ import buildcraft.core.utils.NBTUtils; public class ItemRobot extends ItemBuildCraft { public ItemRobot() { - super(CreativeTabBuildCraft.ITEMS); + super(CreativeTabBuildCraft.BOARDS); } public EntityRobot createRobot(ItemStack stack, World world) { @@ -97,4 +102,21 @@ public class ItemRobot extends ItemBuildCraft { return robot; } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(BuildCraftSilicon.robotItem)); + + for (RedstoneBoardNBT nbt : RedstoneBoardRegistry.instance.getAllBoardNBTs()) { + ItemStack boardStack = new ItemStack(BuildCraftSilicon.redstoneBoard); + NBTTagCompound nbtData = NBTUtils.getItemData(boardStack); + nbt.createBoard(nbtData); + + ItemStack robotStack = createRobotStack(boardStack); + + itemList.add(robotStack.copy()); + } + } } diff --git a/common/buildcraft/core/robots/AIRobotCraftFurnace.java b/common/buildcraft/core/robots/AIRobotCraftFurnace.java index 2a767a0f..153cb3d4 100755 --- a/common/buildcraft/core/robots/AIRobotCraftFurnace.java +++ b/common/buildcraft/core/robots/AIRobotCraftFurnace.java @@ -21,8 +21,10 @@ import buildcraft.api.core.BlockIndex; 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.StackHelper; +import buildcraft.core.inventory.Transactor; import buildcraft.core.inventory.filters.ArrayStackFilter; import buildcraft.core.inventory.filters.IStackFilter; @@ -35,6 +37,9 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric { private ItemStack input; private DockingStation stationFound; private TileEntityFurnace furnace; + private boolean craftStarted = false; + + private int waitedTime = 0; public AIRobotCraftFurnace(EntityRobotBase iRobot) { super(iRobot); @@ -54,39 +59,60 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric { @Override public void update() { if (furnace != null) { - if (furnace.getStackInSlot(FUEL_SLOT) == null && getItem(new FuelFilter()) == null) { - startDelegateAI(new AIRobotGotoStationAndLoad(robot, new FuelFilter(), robot.getZoneToWork())); + if (!craftStarted) { + if (furnace.getStackInSlot(FUEL_SLOT) == null && getItem(new FuelFilter()) == null) { + startDelegateAI(new AIRobotGotoStationAndLoad(robot, new FuelFilter(), robot.getZoneToWork())); - return; + return; + } + + if (getItem(new ArrayStackFilter(input)) == null) { + startDelegateAI(new AIRobotGotoStationAndLoad(robot, new ArrayStackFilter(input), + robot.getZoneToWork())); + + return; + } + + if (robot.getDockingStation() != stationFound) { + startDelegateAI(new AIRobotGotoStation(robot, stationFound)); + + return; + } + + if (furnace.getStackInSlot(FUEL_SLOT) == null) { + IInvSlot s = getItem(new FuelFilter()); + furnace.setInventorySlotContents(FUEL_SLOT, s.decreaseStackInSlot(1)); + } + + if (furnace.getStackInSlot(INPUT_SLOT) == null) { + IInvSlot s = getItem(new ArrayStackFilter(input)); + furnace.setInventorySlotContents(INPUT_SLOT, s.decreaseStackInSlot(1)); + } + + craftStarted = true; + + if (!robot.hasFreeSlot()) { + startDelegateAI(new AIRobotGotoStationAndUnload(robot)); + } + } else { + waitedTime++; + + if (waitedTime > 40 && furnace.getStackInSlot(OUTPUT_SLOT) != null) { + if (robot.hasFreeSlot()) { + ItemStack stack = furnace.decrStackSize(OUTPUT_SLOT, 1); + + if (stack != null) { + ITransactor transactor = Transactor.getTransactorFor(robot); + transactor.add(stack, ForgeDirection.UNKNOWN, true); + crafted = true; + } + } + + terminate(); + } else if (waitedTime > 20 * 60) { + terminate(); + } } - - if (getItem(new ArrayStackFilter(input)) == null) { - startDelegateAI(new AIRobotGotoStationAndLoad(robot, new ArrayStackFilter(input), robot.getZoneToWork())); - - return; - } - - if (robot.getDockingStation() != stationFound) { - startDelegateAI(new AIRobotGotoStation(robot, stationFound)); - - return; - } - - // TODO: Does this need a timing thing? - - if (furnace.getStackInSlot(FUEL_SLOT) == null) { - IInvSlot s = getItem(new FuelFilter()); - furnace.setInventorySlotContents(FUEL_SLOT, s.decreaseStackInSlot(1)); - } - - if (furnace.getStackInSlot(INPUT_SLOT) == null) { - IInvSlot s = getItem(new ArrayStackFilter(input)); - furnace.setInventorySlotContents(INPUT_SLOT, s.decreaseStackInSlot(1)); - } - - // TODO: Create a delegate AI, waiting until the thing is done - - terminate(); } } @@ -108,11 +134,11 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric { BlockIndex index = new BlockIndex(furnace); - if (!reserveBlock(index)) { + if (!robot.getRegistry().take(new ResourceIdBlock(index), robot)) { terminate(); } - robot.reserveStation(stationFound); + stationFound.take(robot); } } else if (ai instanceof AIRobotGotoStationAndLoad) { @@ -166,7 +192,7 @@ public class AIRobotCraftFurnace extends AIRobotCraftGeneric { + dir.offsetY, b.z + dir.offsetZ); - if (!isFreeBlock(index)) { + if (robot.getRegistry().isTaken(new ResourceIdBlock(index))) { continue; } diff --git a/common/buildcraft/core/robots/AIRobotCraftGeneric.java b/common/buildcraft/core/robots/AIRobotCraftGeneric.java index fe6910fe..ce81144b 100755 --- a/common/buildcraft/core/robots/AIRobotCraftGeneric.java +++ b/common/buildcraft/core/robots/AIRobotCraftGeneric.java @@ -25,8 +25,19 @@ public abstract class AIRobotCraftGeneric extends AIRobot { protected abstract ArrayList tryCraft(boolean doRemove); + @Override + public void end() { + robot.releaseResources(); + } + @Override public boolean success() { return crafted; } + + @Override + public double getEnergyCost() { + return 3; + } + } diff --git a/common/buildcraft/core/robots/AIRobotFetchAndEquipItemStack.java b/common/buildcraft/core/robots/AIRobotFetchAndEquipItemStack.java index 9b8d38c1..0191a48a 100755 --- a/common/buildcraft/core/robots/AIRobotFetchAndEquipItemStack.java +++ b/common/buildcraft/core/robots/AIRobotFetchAndEquipItemStack.java @@ -55,9 +55,9 @@ public class AIRobotFetchAndEquipItemStack extends AIRobot { ItemStack itemFound = null; for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { - TileEntity nearbyTile = robot.worldObj.getTileEntity(station.pipe.xCoord + dir.offsetX, - station.pipe.yCoord - + dir.offsetY, station.pipe.zCoord + dir.offsetZ); + TileEntity nearbyTile = robot.worldObj.getTileEntity(station.x() + dir.offsetX, + station.y() + + dir.offsetY, station.z() + dir.offsetZ); if (nearbyTile != null && nearbyTile instanceof IInventory) { ITransactor trans = Transactor.getTransactorFor(nearbyTile); diff --git a/common/buildcraft/core/robots/AIRobotGoAndLinkToDock.java b/common/buildcraft/core/robots/AIRobotGoAndLinkToDock.java index 3b31fb06..e4a56735 100755 --- a/common/buildcraft/core/robots/AIRobotGoAndLinkToDock.java +++ b/common/buildcraft/core/robots/AIRobotGoAndLinkToDock.java @@ -30,11 +30,11 @@ public class AIRobotGoAndLinkToDock extends AIRobot { if (station == robot.getLinkedStation() && station == robot.getDockingStation()) { terminate(); } else { - if (robot.linkToStation(station)) { + if (station.takeAsMain(robot)) { startDelegateAI(new AIRobotGotoBlock(robot, - station.pipe.xCoord + station.side.offsetX * 2, - station.pipe.yCoord + station.side.offsetY * 2, - station.pipe.zCoord + station.side.offsetZ * 2)); + station.x() + station.side.offsetX * 2, + station.y() + station.side.offsetY * 2, + station.z() + station.side.offsetZ * 2)); } else { terminate(); } @@ -45,9 +45,9 @@ public class AIRobotGoAndLinkToDock extends AIRobot { public void delegateAIEnded(AIRobot ai) { if (ai instanceof AIRobotGotoBlock) { startDelegateAI(new AIRobotStraightMoveTo(robot, - station.pipe.xCoord + 0.5F + station.side.offsetX * 0.5F, - station.pipe.yCoord + 0.5F + station.side.offsetY * 0.5F, - station.pipe.zCoord + 0.5F + station.side.offsetZ * 0.5F)); + station.x() + 0.5F + station.side.offsetX * 0.5F, + station.y() + 0.5F + station.side.offsetY * 0.5F, + station.z() + 0.5F + station.side.offsetZ * 0.5F)); } else { robot.dock(station); station = null; @@ -60,7 +60,7 @@ public class AIRobotGoAndLinkToDock extends AIRobot { // If there's still a station targeted, it was not reached. The AI has // probably been interrupted. Cancel reservation. if (station != null) { - robot.reserveStation(null); + station.release(robot); } } } diff --git a/common/buildcraft/core/robots/AIRobotGotoSleep.java b/common/buildcraft/core/robots/AIRobotGotoSleep.java index 4ceafe12..ab7cb7ca 100755 --- a/common/buildcraft/core/robots/AIRobotGotoSleep.java +++ b/common/buildcraft/core/robots/AIRobotGotoSleep.java @@ -19,6 +19,7 @@ public class AIRobotGotoSleep extends AIRobot { @Override public void start() { + robot.getRegistry().releaseResources(robot); startDelegateAI(new AIRobotGotoStation(robot, robot.getLinkedStation())); } diff --git a/common/buildcraft/core/robots/AIRobotGotoStation.java b/common/buildcraft/core/robots/AIRobotGotoStation.java index e01b2dfe..2e41ae1a 100755 --- a/common/buildcraft/core/robots/AIRobotGotoStation.java +++ b/common/buildcraft/core/robots/AIRobotGotoStation.java @@ -8,30 +8,41 @@ */ package buildcraft.core.robots; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.core.BlockIndex; import buildcraft.api.robots.AIRobot; import buildcraft.api.robots.EntityRobotBase; import buildcraft.api.robots.IDockingStation; public class AIRobotGotoStation extends AIRobot { - private IDockingStation station; + private BlockIndex stationIndex; + private ForgeDirection stationSide; public AIRobotGotoStation(EntityRobotBase iRobot) { super(iRobot); } - public AIRobotGotoStation(EntityRobotBase iRobot, IDockingStation iStation) { + public AIRobotGotoStation(EntityRobotBase iRobot, IDockingStation station) { super(iRobot); - station = iStation; + stationIndex = station.index(); + stationSide = station.side(); } @Override public void start() { - if (station == robot.getDockingStation()) { + DockingStation station = + robot.getRegistry().getStation(stationIndex.x, stationIndex.y, stationIndex.z, + stationSide); + + if (station == null || station == robot.getDockingStation()) { terminate(); } else { - if (robot.reserveStation(station)) { + if (station.take(robot)) { startDelegateAI(new AIRobotGotoBlock(robot, station.x() + station.side().offsetX * 2, station.y() + station.side().offsetY * 2, @@ -42,42 +53,36 @@ public class AIRobotGotoStation extends AIRobot { } } - @Override - public void update() { - // this should not happen, always terminate in this situation - terminate(); - } - @Override public void delegateAIEnded(AIRobot ai) { - if (ai instanceof AIRobotGotoBlock) { - if (station == null) { - // in case of a load from disk - station = robot.getReservedStation(); - } + DockingStation station = + robot.getRegistry().getStation(stationIndex.x, stationIndex.y, stationIndex.z, + stationSide); + if (station == null) { + terminate(); + } else if (ai instanceof AIRobotGotoBlock) { startDelegateAI(new AIRobotStraightMoveTo(robot, - station.x() + 0.5F + station.side().offsetX * 0.5F, - station.y() + 0.5F + station.side().offsetY * 0.5F, - station.z() + 0.5F + station.side().offsetZ * 0.5F)); + stationIndex.x + 0.5F + stationSide.offsetX * 0.5F, + stationIndex.y + 0.5F + stationSide.offsetY * 0.5F, + stationIndex.z + 0.5F + stationSide.offsetZ * 0.5F)); } else { - if (station == null) { - // in case of a load from disk - station = robot.getReservedStation(); - } - robot.dock(station); - station = null; terminate(); } } @Override - public void end() { - // If there's still a station targeted, it was not reached. The AI has - // probably been interrupted. Cancel reservation. - if (station != null) { - robot.reserveStation(null); - } + public void writeSelfToNBT(NBTTagCompound nbt) { + NBTTagCompound indexNBT = new NBTTagCompound(); + stationIndex.writeTo(indexNBT); + nbt.setTag("stationIndex", indexNBT); + nbt.setByte("stationSide", (byte) stationSide.ordinal()); + } + + @Override + public void loadSelfFromNBT(NBTTagCompound nbt) { + stationIndex = new BlockIndex(nbt.getCompoundTag("stationIndex")); + stationSide = ForgeDirection.values()[nbt.getByte("stationSide")]; } } diff --git a/common/buildcraft/core/robots/AIRobotGotoStationAndUnload.java b/common/buildcraft/core/robots/AIRobotGotoStationAndUnload.java new file mode 100755 index 00000000..0087f2ef --- /dev/null +++ b/common/buildcraft/core/robots/AIRobotGotoStationAndUnload.java @@ -0,0 +1,51 @@ +/** + * 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 buildcraft.api.core.IZone; +import buildcraft.api.robots.AIRobot; +import buildcraft.api.robots.EntityRobotBase; + +public class AIRobotGotoStationAndUnload extends AIRobot { + + private boolean found = false; + private IZone zone; + + public AIRobotGotoStationAndUnload(EntityRobotBase iRobot) { + super(iRobot); + } + + public AIRobotGotoStationAndUnload(EntityRobotBase iRobot, IZone iZone) { + super(iRobot); + + zone = iZone; + } + + @Override + public void start() { + startDelegateAI(new AIRobotGotoStationToUnload(robot, zone)); + } + + @Override + public void delegateAIEnded(AIRobot ai) { + if (ai instanceof AIRobotGotoStationToUnload) { + if (ai.success()) { + found = true; + startDelegateAI(new AIRobotUnload(robot)); + } else { + terminate(); + } + } + } + + @Override + public boolean success() { + return found; + } +} diff --git a/common/buildcraft/core/robots/AIRobotGotoStationToLoad.java b/common/buildcraft/core/robots/AIRobotGotoStationToLoad.java index a39b0f01..1ed60f3e 100755 --- a/common/buildcraft/core/robots/AIRobotGotoStationToLoad.java +++ b/common/buildcraft/core/robots/AIRobotGotoStationToLoad.java @@ -67,9 +67,9 @@ public class AIRobotGotoStationToLoad extends AIRobot { public boolean matches(DockingStation station) { boolean actionFound = false; - Pipe pipe = station.pipe.pipe; + Pipe pipe = station.getPipe().pipe; - for (ActionSlot s : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot s : new ActionIterator(pipe)) { if (s.action instanceof ActionStationProvideItems) { StatementParameterStackFilter param = new StatementParameterStackFilter(s.parameters); diff --git a/common/buildcraft/core/robots/AIRobotGotoStationToUnload.java b/common/buildcraft/core/robots/AIRobotGotoStationToUnload.java index 8db9730c..f82b13b1 100755 --- a/common/buildcraft/core/robots/AIRobotGotoStationToUnload.java +++ b/common/buildcraft/core/robots/AIRobotGotoStationToUnload.java @@ -58,14 +58,14 @@ public class AIRobotGotoStationToUnload extends AIRobot { private class StationInventory implements IStationFilter { @Override public boolean matches(DockingStation station) { - Pipe pipe = station.pipe.pipe; + Pipe pipe = station.getPipe().pipe; for (IInvSlot robotSlot : InventoryIterator.getIterable(robot, ForgeDirection.UNKNOWN)) { if (robotSlot.getStackInSlot() == null) { continue; } - for (ActionSlot s : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot s : new ActionIterator(pipe)) { if (s.action instanceof ActionStationRequestItems) { if (((ActionStationRequestItems) s.action).insert(station, (EntityRobot) robot, s, robotSlot, false)) { return true; diff --git a/common/buildcraft/core/robots/AIRobotLoad.java b/common/buildcraft/core/robots/AIRobotLoad.java index 5869017c..eb1d887c 100755 --- a/common/buildcraft/core/robots/AIRobotLoad.java +++ b/common/buildcraft/core/robots/AIRobotLoad.java @@ -64,9 +64,9 @@ public class AIRobotLoad extends AIRobot { DockingStation station = (DockingStation) robot.getDockingStation(); for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { - TileEntity nearbyTile = robot.worldObj.getTileEntity(station.pipe.xCoord + dir.offsetX, - station.pipe.yCoord - + dir.offsetY, station.pipe.zCoord + dir.offsetZ); + TileEntity nearbyTile = robot.worldObj.getTileEntity(station.x() + dir.offsetX, + station.y() + + dir.offsetY, station.z() + dir.offsetZ); if (nearbyTile != null && nearbyTile instanceof IInventory) { IInventory tileInventory = (IInventory) nearbyTile; @@ -78,7 +78,7 @@ public class AIRobotLoad extends AIRobot { if (stack != null) { boolean allowed = false; - for (ActionSlot s : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot s : new ActionIterator(station.getPipe().pipe)) { if (s.action instanceof ActionStationProvideItems) { StatementParameterStackFilter param = new StatementParameterStackFilter( s.parameters); diff --git a/common/buildcraft/core/robots/AIRobotRecharge.java b/common/buildcraft/core/robots/AIRobotRecharge.java index 11e38792..f432efbd 100755 --- a/common/buildcraft/core/robots/AIRobotRecharge.java +++ b/common/buildcraft/core/robots/AIRobotRecharge.java @@ -23,17 +23,19 @@ public class AIRobotRecharge extends AIRobot { @Override public void start() { + robot.getRegistry().releaseResources(robot); + startDelegateAI(new AIRobotSearchAndGotoStation(robot, new IStationFilter() { @Override public boolean matches(DockingStation station) { - return station.pipe.getPipeType() == PipeType.POWER; + return station.getPipe().getPipeType() == PipeType.POWER; } }, null)); } @Override public void update() { - PipeTransportPower powerProvider = (PipeTransportPower) ((DockingStation) robot.getDockingStation()).pipe.pipe.transport; + PipeTransportPower powerProvider = (PipeTransportPower) ((DockingStation) robot.getDockingStation()).getPipe().pipe.transport; powerProvider.requestEnergy(robot.getDockingStation().side(), 100); robot.setEnergy(robot.getEnergy() @@ -48,7 +50,7 @@ public class AIRobotRecharge extends AIRobot { public void delegateAIEnded(AIRobot ai) { if (ai instanceof AIRobotSearchAndGotoStation) { if (robot.getDockingStation() == null - || !(((DockingStation) robot.getDockingStation()).pipe.pipe.transport instanceof PipeTransportPower)) { + || !(((DockingStation) robot.getDockingStation()).getPipe().pipe.transport instanceof PipeTransportPower)) { terminate(); } } diff --git a/common/buildcraft/core/robots/AIRobotSearchStation.java b/common/buildcraft/core/robots/AIRobotSearchStation.java index 86ba6de3..4ee59afd 100755 --- a/common/buildcraft/core/robots/AIRobotSearchStation.java +++ b/common/buildcraft/core/robots/AIRobotSearchStation.java @@ -10,7 +10,6 @@ package buildcraft.core.robots; import buildcraft.api.core.IZone; import buildcraft.api.robots.AIRobot; -import buildcraft.api.robots.DockingStationRegistry; import buildcraft.api.robots.EntityRobotBase; import buildcraft.api.robots.IDockingStation; import buildcraft.silicon.statements.ActionStationForbidRobot; @@ -44,10 +43,10 @@ public class AIRobotSearchStation extends AIRobot { double potentialStationDistance = Float.MAX_VALUE; DockingStation potentialStation = null; - for (IDockingStation d : DockingStationRegistry.getStations()) { + for (IDockingStation d : robot.getRegistry().getStations()) { DockingStation station = (DockingStation) d; - if (station.reserved() != null) { + if (d.isTaken() && d.robotIdTaking() != robot.getRobotId()) { continue; } diff --git a/common/buildcraft/core/robots/AIRobotSleep.java b/common/buildcraft/core/robots/AIRobotSleep.java index d84b414d..e3865834 100755 --- a/common/buildcraft/core/robots/AIRobotSleep.java +++ b/common/buildcraft/core/robots/AIRobotSleep.java @@ -25,7 +25,7 @@ public class AIRobotSleep extends AIRobot { @Override public void preempt(AIRobot ai) { - for (ActionSlot s : new ActionIterator(((DockingStation) robot.getLinkedStation()).pipe.pipe)) { + for (ActionSlot s : new ActionIterator(((DockingStation) robot.getLinkedStation()).getPipe().pipe)) { if (s.action instanceof ActionRobotWakeUp) { terminate(); } diff --git a/common/buildcraft/core/robots/AIRobotUnload.java b/common/buildcraft/core/robots/AIRobotUnload.java index ea94df00..d27366b1 100755 --- a/common/buildcraft/core/robots/AIRobotUnload.java +++ b/common/buildcraft/core/robots/AIRobotUnload.java @@ -47,14 +47,14 @@ public class AIRobotUnload extends AIRobot { return false; } - Pipe pipe = station.pipe.pipe; + Pipe pipe = station.getPipe().pipe; for (IInvSlot robotSlot : InventoryIterator.getIterable(robot, ForgeDirection.UNKNOWN)) { if (robotSlot.getStackInSlot() == null) { continue; } - for (ActionSlot s : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot s : new ActionIterator(pipe)) { if (s.action instanceof ActionStationRequestItems) { if (((ActionStationRequestItems) s.action) .insert(station, (EntityRobot) robot, s, robotSlot, true)) { diff --git a/common/buildcraft/core/robots/DockingStation.java b/common/buildcraft/core/robots/DockingStation.java index a14225ba..6626192f 100755 --- a/common/buildcraft/core/robots/DockingStation.java +++ b/common/buildcraft/core/robots/DockingStation.java @@ -9,40 +9,73 @@ package buildcraft.core.robots; 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.EntityRobotBase; import buildcraft.api.robots.IDockingStation; import buildcraft.transport.TileGenericPipe; public class DockingStation implements IDockingStation { - public TileGenericPipe pipe; public ForgeDirection side; - private EntityRobotBase linked; - private EntityRobotBase reserved; + public World world; + + private long robotTakingId = EntityRobotBase.NULL_ROBOT_ID; + private EntityRobotBase robotTaking; + + private boolean linkIsMain = false; + + private BlockIndex index; + private TileGenericPipe pipe; + + public DockingStation(BlockIndex iIndex, ForgeDirection iSide) { + index = iIndex; + side = iSide; + } public DockingStation(TileGenericPipe iPipe, ForgeDirection iSide) { + index = new BlockIndex(iPipe); pipe = iPipe; side = iSide; + world = iPipe.getWorld(); } public DockingStation() { } + public boolean isMainStation() { + return linkIsMain; + } + + public TileGenericPipe getPipe() { + if (pipe == null) { + pipe = (TileGenericPipe) world.getTileEntity(index.x, index.y, index.z); + } + + if (pipe == null || pipe.isInvalid()) { + // Inconsistency - remove this pipe from the registry. + RobotRegistry.getRegistry(world).removeStation(this); + pipe = null; + } + + return pipe; + } + @Override public int x() { - return pipe.xCoord; + return index.x; } @Override public int y() { - return pipe.yCoord; + return index.y; } @Override public int z() { - return pipe.zCoord; + return index.z; } @Override @@ -51,60 +84,123 @@ public class DockingStation implements IDockingStation { } @Override - public EntityRobotBase reserved() { - return reserved; + public EntityRobotBase robotTaking() { + if (robotTakingId == EntityRobotBase.NULL_ROBOT_ID) { + return null; + } else if (robotTaking == null) { + robotTaking = RobotRegistry.getRegistry(world).getLoadedRobot(robotTakingId); + } + + return robotTaking; } @Override - public EntityRobotBase linked() { - return linked; + public long linkedId() { + return robotTakingId; } - public boolean reserve(EntityRobotBase robot) { - if ((linked == null || linked == robot) && reserved == null) { - reserved = robot; - pipe.scheduleRenderUpdate(); + public boolean takeAsMain(EntityRobotBase robot) { + if (robotTaking == null) { + linkIsMain = true; + robotTaking = robot; + robotTakingId = robot.getRobotId(); + getPipe().scheduleRenderUpdate(); + RobotRegistry.getRegistry(world).markDirty(); + ((EntityRobot) robot).setMainStation(this); + RobotRegistry.getRegistry(world).take(this, robot.getRobotId()); + return true; } else { return false; } } - public boolean link(EntityRobotBase robot) { - if (linked == null) { - linked = robot; - pipe.scheduleRenderUpdate(); + public boolean take(EntityRobotBase robot) { + if (robotTaking == null) { + linkIsMain = false; + robotTaking = robot; + robotTakingId = robot.getRobotId(); + getPipe().scheduleRenderUpdate(); + RobotRegistry.getRegistry(world).markDirty(); + RobotRegistry.getRegistry(world).take(this, robot.getRobotId()); + return true; } else { - return false; + return robot.getRobotId() == robotTakingId; } } - public void unreserve(EntityRobotBase robot) { - if (reserved == robot) { - reserved = null; - pipe.scheduleRenderUpdate(); + public void release(EntityRobotBase robot) { + if (robotTaking == robot && !linkIsMain) { + linkIsMain = false; + robotTaking = null; + robotTakingId = EntityRobotBase.NULL_ROBOT_ID; + getPipe().scheduleRenderUpdate(); + RobotRegistry.getRegistry(world).markDirty(); + RobotRegistry.getRegistry(world).release(this, robot.getRobotId()); } } - public void unlink(EntityRobotBase robot) { - if (linked == robot) { - linked = null; - pipe.scheduleRenderUpdate(); + /** + * Same a release but doesn't clear the registry (presumably called from the + * registry). + */ + public void unsafeRelease(EntityRobotBase robot) { + if (robotTaking == robot) { + robotTaking = null; + robotTakingId = EntityRobotBase.NULL_ROBOT_ID; + getPipe().scheduleRenderUpdate(); } } @Override public void writeToNBT(NBTTagCompound nbt) { - nbt.setInteger("x", pipe.xCoord); - nbt.setInteger("y", pipe.yCoord); - nbt.setInteger("z", pipe.zCoord); - nbt.setInteger("side", side.ordinal()); + NBTTagCompound indexNBT = new NBTTagCompound(); + index.writeTo(indexNBT); + nbt.setTag("index", indexNBT); + nbt.setByte("side", (byte) side.ordinal()); + nbt.setBoolean("isMain", linkIsMain); + nbt.setLong("robotId", robotTakingId); } @Override public void readFromNBT(NBTTagCompound nbt) { + index = new BlockIndex (nbt.getCompoundTag("index")); + side = ForgeDirection.values()[nbt.getByte("side")]; + linkIsMain = nbt.getBoolean("isMain"); + robotTakingId = nbt.getLong("robotId"); + } + @Override + public boolean isTaken() { + return robotTakingId != EntityRobotBase.NULL_ROBOT_ID; + } + + @Override + public long robotIdTaking() { + return robotTakingId; + } + + @Override + public BlockIndex index() { + return index; + } + + @Override + public String toString () { + return "{" + index.x + ", " + index.y + ", " + index.z + ", " + side + " :" + robotTakingId + "}"; + } + + public boolean linkIsDocked() { + if (isTaken()) { + return robotTaking().getDockingStation() == this; + } else { + return false; + } + } + + public boolean canRelease() { + return !isMainStation() && !linkIsDocked(); } } diff --git a/common/buildcraft/core/robots/EntityRobot.java b/common/buildcraft/core/robots/EntityRobot.java index f3156d89..aab86717 100755 --- a/common/buildcraft/core/robots/EntityRobot.java +++ b/common/buildcraft/core/robots/EntityRobot.java @@ -31,12 +31,14 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftSilicon; import buildcraft.api.boards.RedstoneBoardNBT; import buildcraft.api.boards.RedstoneBoardRegistry; import buildcraft.api.boards.RedstoneBoardRobot; import buildcraft.api.boards.RedstoneBoardRobotNBT; +import buildcraft.api.core.BlockIndex; import buildcraft.api.core.IZone; import buildcraft.api.core.SafeTimeTracker; import buildcraft.api.mj.MjBattery; @@ -72,8 +74,13 @@ public class EntityRobot extends EntityRobotBase implements public SafeTimeTracker scanForTasks = new SafeTimeTracker (40, 10); public LaserData laser = new LaserData(); - public IDockingStation reservedDockingStation; public IDockingStation linkedDockingStation; + public BlockIndex linkedDockingStationIndex; + public ForgeDirection linkedDockingStationSide; + + public BlockIndex currentDockingStationIndex; + public ForgeDirection currentDockingStationSide; + public boolean isDocked = false; public NBTTagCompound originalBoardNBT; @@ -87,11 +94,13 @@ public class EntityRobot extends EntityRobotBase implements public float itemActiveStage = 0; public long lastUpdateTime = 0; + private DockingStation currentDockingStation; + private boolean needsUpdate = false; private ItemStack[] inv = new ItemStack[4]; private String boardID; private ResourceLocation texture; - private IDockingStation currentDockingStation; + private WeakHashMap unreachableEntities = new WeakHashMap(); private NBTTagList stackRequestNBT; @@ -102,6 +111,8 @@ public class EntityRobot extends EntityRobotBase implements private boolean firstUpdateDone = false; + private long robotId = EntityRobotBase.NULL_ROBOT_ID; + public EntityRobot(World world, NBTTagCompound boardNBT) { this(world); @@ -209,10 +220,14 @@ public class EntityRobot extends EntityRobotBase implements if (stackRequestNBT != null) { } + + if (!worldObj.isRemote) { + getRegistry().registerRobot(this); + } } @Override - public void onUpdate() { + public void onEntityUpdate() { if (!firstUpdateDone) { firstUpdate(); firstUpdateDone = true; @@ -237,29 +252,32 @@ public class EntityRobot extends EntityRobotBase implements } if (!worldObj.isRemote) { - if (linkedDockingStation instanceof FakeDockingStation) { - // try to load the docking station. If the chunk can be loaded - // but not the docking station, then the expecting docking - // station is not around, kill the robot. - IDockingStation station = ((FakeDockingStation) linkedDockingStation).getRealStation(worldObj); + if (linkedDockingStation == null) { + linkedDockingStation = RobotRegistry.getRegistry(worldObj).getStation( + linkedDockingStationIndex.x, + linkedDockingStationIndex.y, + linkedDockingStationIndex.z, + linkedDockingStationSide); + + linkedDockingStationIndex = null; + + if (linkedDockingStation.robotTaking() != this) { + // Error at load time, the expected linked stations is not + // properly set, kill this robot. - if (station != null) { - linkToStation(station); - } else { setDead(); + return; } } - if (reservedDockingStation instanceof FakeDockingStation) { - IDockingStation station = ((FakeDockingStation) reservedDockingStation).getRealStation(worldObj); + if (currentDockingStationIndex != null) { + currentDockingStation = RobotRegistry.getRegistry(worldObj).getStation( + currentDockingStationIndex.x, + currentDockingStationIndex.y, + currentDockingStationIndex.z, + currentDockingStationSide); - if (station != null) { - reserveStation(station); - } - } - - if (currentDockingStation instanceof FakeDockingStation) { - currentDockingStation = ((FakeDockingStation) currentDockingStation).getRealStation(worldObj); + currentDockingStationIndex = null; } if (linkedDockingStation != null) { @@ -271,7 +289,7 @@ public class EntityRobot extends EntityRobotBase implements } } - super.onUpdate(); + super.onEntityUpdate(); } public void setRegularBoundingBox() { @@ -375,19 +393,19 @@ public class EntityRobot extends EntityRobotBase implements super.writeEntityToNBT(nbt); NBTTagCompound linkedStationNBT = new NBTTagCompound(); - linkedDockingStation.writeToNBT(linkedStationNBT); + NBTTagCompound linkedStationIndexNBT = new NBTTagCompound(); + linkedDockingStation.index().writeTo(linkedStationIndexNBT); + linkedStationNBT.setTag("index", linkedStationIndexNBT); + linkedStationNBT.setByte("side", (byte) linkedDockingStation.side().ordinal()); nbt.setTag("linkedStation", linkedStationNBT); - if (reservedDockingStation != null) { - NBTTagCompound stationNBT = new NBTTagCompound(); - reservedDockingStation.writeToNBT(stationNBT); - nbt.setTag("reservedStation", stationNBT); - } - if (currentDockingStation != null) { - NBTTagCompound stationNBT = new NBTTagCompound(); - currentDockingStation.writeToNBT(stationNBT); - nbt.setTag("currentStation", stationNBT); + NBTTagCompound currentStationNBT = new NBTTagCompound(); + NBTTagCompound currentStationIndexNBT = new NBTTagCompound(); + currentDockingStation.index().writeTo(currentStationIndexNBT); + currentStationNBT.setTag("index", currentStationIndexNBT); + currentStationNBT.setByte("side", (byte) currentDockingStation.side().ordinal()); + nbt.setTag("currentStation", currentStationNBT); } NBTTagCompound nbtLaser = new NBTTagCompound(); @@ -438,23 +456,23 @@ public class EntityRobot extends EntityRobotBase implements } nbt.setTag("stackRequests", requestsNBT); + + nbt.setLong("robotId", robotId); } @Override public void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); - linkedDockingStation = new FakeDockingStation(); - linkedDockingStation.readFromNBT(nbt.getCompoundTag("linkedStation")); - - if (nbt.hasKey("reservedStation")) { - reservedDockingStation = new FakeDockingStation(); - reservedDockingStation.readFromNBT(nbt.getCompoundTag("reservedStation")); - } + NBTTagCompound linkedStationNBT = nbt.getCompoundTag("linkedStation"); + linkedDockingStationIndex = new BlockIndex(linkedStationNBT.getCompoundTag("index")); + linkedDockingStationSide = ForgeDirection.values()[linkedStationNBT.getByte("side")]; if (nbt.hasKey("currentStation")) { - currentDockingStation = new FakeDockingStation(); - currentDockingStation.readFromNBT(nbt.getCompoundTag("currentStation")); + NBTTagCompound currentStationNBT = nbt.getCompoundTag("currentStation"); + currentDockingStationIndex = new BlockIndex(currentStationNBT.getCompoundTag("index")); + currentDockingStationSide = ForgeDirection.values()[currentStationNBT.getByte("side")]; + } laser.readFromNBT(nbt.getCompoundTag("laser")); @@ -484,68 +502,38 @@ public class EntityRobot extends EntityRobotBase implements dataWatcher.updateObject(16, board.getNBTHandler().getID()); stackRequestNBT = nbt.getTagList("stackRequests", Constants.NBT.TAG_COMPOUND); + + if (nbt.hasKey("robotId")) { + robotId = nbt.getLong("robotId"); + } } @Override public void dock(IDockingStation station) { - currentDockingStation = station; + currentDockingStation = (DockingStation) station; } @Override public void undock() { - if (currentDockingStation != null && currentDockingStation instanceof DockingStation) { - ((DockingStation) currentDockingStation).unreserve(this); + if (currentDockingStation != null) { + currentDockingStation.release(this); currentDockingStation = null; } } @Override public DockingStation getDockingStation() { - return (DockingStation) currentDockingStation; + return currentDockingStation; } - @Override - public boolean reserveStation(IDockingStation iStation) { + public void setMainStation(IDockingStation iStation) { DockingStation station = (DockingStation) iStation; - if (station == null) { - if (reservedDockingStation != null && reservedDockingStation instanceof DockingStation) { - ((DockingStation) reservedDockingStation).unreserve(this); - } - - reservedDockingStation = null; - - return true; - } else if (station.reserved() == this) { - return true; - } else if (station.reserve(this)) { - if (reservedDockingStation != null && reservedDockingStation instanceof DockingStation) { - ((DockingStation) reservedDockingStation).unreserve(this); - } - - reservedDockingStation = station; - return true; - } else { - return false; + if (linkedDockingStation != null && linkedDockingStation != station) { + ((DockingStation) linkedDockingStation).release(this); } - } - @Override - public boolean linkToStation(IDockingStation iStation) { - DockingStation station = (DockingStation) iStation; - - if (station.linked() == this) { - return true; - } else if (station.link(this)) { - if (linkedDockingStation != null && linkedDockingStation instanceof DockingStation) { - ((DockingStation) linkedDockingStation).unlink(this); - } - - linkedDockingStation = station; - return true; - } else { - return false; - } + linkedDockingStation = station; } @Override @@ -553,10 +541,6 @@ public class EntityRobot extends EntityRobotBase implements return null; } - public boolean acceptTask (IRobotTask task) { - return false; - } - @Override public int getSizeInventory() { return inv.length; @@ -708,11 +692,6 @@ public class EntityRobot extends EntityRobotBase implements return linkedDockingStation; } - @Override - public IDockingStation getReservedStation() { - return reservedDockingStation; - } - @SideOnly(Side.CLIENT) @Override public boolean isInRangeToRenderDist(double par1) { @@ -769,7 +748,7 @@ public class EntityRobot extends EntityRobotBase implements @Override public IZone getZoneToWork() { if (linkedDockingStation instanceof DockingStation) { - for (ActionSlot s : new ActionIterator(((DockingStation) linkedDockingStation).pipe.pipe)) { + for (ActionSlot s : new ActionIterator(((DockingStation) linkedDockingStation).getPipe().pipe)) { if (s.action instanceof ActionRobotWorkInArea) { IZone zone = ActionRobotWorkInArea.getArea(s); @@ -794,6 +773,17 @@ public class EntityRobot extends EntityRobotBase implements return false; } + @Override + public boolean hasFreeSlot() { + for (ItemStack element : inv) { + if (element == null) { + return true; + } + } + + return false; + } + @Override public void unreachableEntityDetected(Entity entity) { unreachableEntities.put(entity, true); @@ -812,19 +802,15 @@ public class EntityRobot extends EntityRobotBase implements // some other way to cope with that problem - such as a manual // charger? - mainAI.abort(); + if (mainAI != null) { + mainAI.abort(); + } ItemStack robotStack = new ItemStack (BuildCraftSilicon.robotItem); NBTUtils.getItemData(robotStack).setTag("board", originalBoardNBT); entityDropItem(robotStack, 0); - if (linkedDockingStation != null && linkedDockingStation instanceof DockingStation) { - ((DockingStation) linkedDockingStation).unlink(this); - } - - if (reservedDockingStation != null && reservedDockingStation instanceof DockingStation) { - ((DockingStation) reservedDockingStation).unreserve(this); - } + getRegistry().killRobot(this); } super.setDead(); @@ -844,4 +830,23 @@ public class EntityRobot extends EntityRobotBase implements public void applyEntityCollision(Entity par1Entity) { } + + public void setUniqueRobotId(long iRobotId) { + robotId = iRobotId; + } + + @Override + public long getRobotId() { + return robotId; + } + + @Override + public RobotRegistry getRegistry() { + return RobotRegistry.getRegistry(worldObj); + } + + @Override + public void releaseResources() { + getRegistry().releaseResources(this); + } } diff --git a/common/buildcraft/core/robots/FakeDockingStation.java b/common/buildcraft/core/robots/FakeDockingStation.java deleted file mode 100755 index 1fa9e464..00000000 --- a/common/buildcraft/core/robots/FakeDockingStation.java +++ /dev/null @@ -1,85 +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.core.robots; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; - -import net.minecraftforge.common.util.ForgeDirection; - -import buildcraft.api.robots.DockingStationRegistry; -import buildcraft.api.robots.EntityRobotBase; -import buildcraft.api.robots.IDockingStation; - -public class FakeDockingStation implements IDockingStation { - - private int x, y, z; - private ForgeDirection side; - - public FakeDockingStation() { - } - - @Override - public int x() { - return x; - } - - @Override - public int y() { - return y; - } - - @Override - public int z() { - return z; - } - - @Override - public ForgeDirection side() { - return side; - } - - @Override - public EntityRobotBase reserved() { - return null; - } - - @Override - public EntityRobotBase linked() { - return null; - } - - @Override - public void writeToNBT(NBTTagCompound nbt) { - nbt.setInteger("x", x); - nbt.setInteger("y", y); - nbt.setInteger("z", z); - nbt.setInteger("side", side.ordinal()); - } - - @Override - public void readFromNBT(NBTTagCompound nbt) { - x = nbt.getInteger("x"); - y = nbt.getInteger("y"); - z = nbt.getInteger("z"); - side = ForgeDirection.values()[nbt.getInteger("side")]; - } - - public DockingStation getRealStation (World world) { - Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); - - if (chunk != null) { - return (DockingStation) DockingStationRegistry.getStation(x, y, z, side); - } else { - return null; - } - } -} - diff --git a/common/buildcraft/core/robots/IRobotTask.java b/common/buildcraft/core/robots/IRobotTask.java deleted file mode 100755 index 67b30977..00000000 --- a/common/buildcraft/core/robots/IRobotTask.java +++ /dev/null @@ -1,19 +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.core.robots; - -public interface IRobotTask { - - void setup(EntityRobot robot); - - void update(EntityRobot robot); - - boolean done(); - -} diff --git a/common/buildcraft/core/robots/IRobotTaskProvider.java b/common/buildcraft/core/robots/IRobotTaskProvider.java deleted file mode 100755 index 8ea71d38..00000000 --- a/common/buildcraft/core/robots/IRobotTaskProvider.java +++ /dev/null @@ -1,50 +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.core.robots; - -import net.minecraft.world.World; - -/** - * Objects able to provide tasks to robots. They should be registered by - * #RobotTaskProviderRegistry - */ -public interface IRobotTaskProvider { - - /** - * Robots will pick up tasks that are provided within a certain range. - * These can be coming from e.g. tile entities or entities. - */ - double getX(); - - double getY(); - - double getZ(); - - World getWorld(); - - /** - * If the provider is not active, it will be eventually removed from the - * list of potential providers. - */ - boolean isActive(); - - /** - * Returns the next task that can be given to the robot in parameter. This - * is a first level of filter. The robot may or may not decide to pick up - * the task. - */ - IRobotTask getNextTask(EntityRobot robot); - - /** - * This is called once a task has been accepted, to be removed from the - * list of available tasks. - */ - void popNextTask(); - -} diff --git a/common/buildcraft/core/robots/ResourceId.java b/common/buildcraft/core/robots/ResourceId.java new file mode 100755 index 00000000..c98e3edb --- /dev/null +++ b/common/buildcraft/core/robots/ResourceId.java @@ -0,0 +1,81 @@ +/** + * 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.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.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.hashCode() * 37) + side.ordinal() * 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("class", getClass().getCanonicalName()); + } + + 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) { + try { + Class clas = Class.forName(nbt.getString("class")); + + ResourceId id = (ResourceId) clas.newInstance(); + id.readFromNBT(nbt); + + return id; + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; + } + + public void taken(long robotId) { + + } + + public void released(long robotId) { + + } +} diff --git a/common/buildcraft/core/robots/ResourceIdBlock.java b/common/buildcraft/core/robots/ResourceIdBlock.java new file mode 100755 index 00000000..166f9b79 --- /dev/null +++ b/common/buildcraft/core/robots/ResourceIdBlock.java @@ -0,0 +1,33 @@ +/** + * 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 ResourceIdBlock extends ResourceId { + + public ResourceIdBlock() { + + } + + public ResourceIdBlock(int x, int y, int z) { + index = new BlockIndex(x, y, z); + } + + public ResourceIdBlock(BlockIndex iIndex) { + index = iIndex; + } + + public ResourceIdBlock(TileEntity tile) { + index = new BlockIndex(tile); + } + +} diff --git a/common/buildcraft/core/robots/RobotRegistry.java b/common/buildcraft/core/robots/RobotRegistry.java new file mode 100755 index 00000000..6a864889 --- /dev/null +++ b/common/buildcraft/core/robots/RobotRegistry.java @@ -0,0 +1,320 @@ +/** + * 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 java.security.InvalidParameterException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; + +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.robots.EntityRobotBase; + +public class RobotRegistry extends WorldSavedData { + + public static RobotRegistry[] registries = new RobotRegistry[256]; + + protected World world; + + private long nextRobotID = Long.MIN_VALUE; + + // TODO: we'll need a way to release resources from "lost robots" at some + // point - one possibility: + // when asking if a resource is available, look for the robot + // if the robot is loaded, ok, keep the resource + // if not, then release the resource automatically + // don't do this for stations, only for resources (stations can be manually + // freed from in-game) + + private HashMap robotsLoaded = new HashMap(); + private HashMap resourcesTaken = new HashMap(); + private HashMap> resourcesTakenByRobot = new HashMap>(); + + private HashMap stations = new HashMap(); + private HashMap> stationsTakenByRobot = new HashMap>(); + + public RobotRegistry(String id) { + super(id); + } + + public long getNextRobotId() { + long result = nextRobotID; + + nextRobotID = nextRobotID + 1; + + return result; + } + + public void registerRobot(EntityRobot robot) { + markDirty(); + + if (robot.getRobotId() == EntityRobotBase.NULL_ROBOT_ID) { + robot.setUniqueRobotId(getNextRobotId()); + } + + robotsLoaded.put(robot.getRobotId(), robot); + } + + public void killRobot(EntityRobot robot) { + markDirty(); + + releaseResources(robot, true); + robotsLoaded.remove(robot.getRobotId()); + } + + public EntityRobot getLoadedRobot(long id) { + if (robotsLoaded.containsKey(id)) { + return robotsLoaded.get(id); + } else { + return null; + } + } + + public boolean isTaken(ResourceId resourceId) { + return resourcesTaken.containsKey(resourceId); + } + + public long robotTaking(ResourceId resourceId) { + if (resourcesTaken.containsKey(resourceId)) { + return resourcesTaken.get(resourceId); + } else { + return EntityRobotBase.NULL_ROBOT_ID; + } + } + + public boolean take(ResourceId resourceId, EntityRobotBase robot) { + markDirty(); + + return take(resourceId, robot.getRobotId()); + } + + public boolean take(ResourceId resourceId, long robotId) { + if (resourceId == null) { + return false; + } + + markDirty(); + + if (!resourcesTaken.containsKey(resourceId)) { + resourcesTaken.put(resourceId, robotId); + + if (!resourcesTakenByRobot.containsKey(robotId)) { + resourcesTakenByRobot.put(robotId, new HashSet()); + } + + resourcesTakenByRobot.get(robotId).add(resourceId); + + resourceId.taken(robotId); + + return true; + } else { + return false; + } + } + + public void release(ResourceId resourceId) { + if (resourceId == null) { + return; + } + + markDirty(); + + if (resourcesTaken.containsKey(resourceId)) { + long robotId = resourcesTaken.get(resourceId); + + resourcesTakenByRobot.get(resourcesTaken.get(resourceId)).remove(resourceId); + resourcesTaken.remove(resourceId); + resourceId.released(robotId); + } + } + + public void releaseResources(EntityRobotBase robot) { + releaseResources(robot, false); + } + + private void releaseResources(EntityRobotBase robot, boolean forceAll) { + markDirty(); + + if (resourcesTakenByRobot.containsKey(robot.getRobotId())) { + HashSet resourceSet = resourcesTakenByRobot.get(robot.getRobotId()); + + ResourceId mainId = null; + + for (ResourceId id : resourceSet) { + release(id); + } + + resourcesTakenByRobot.remove(robot.getRobotId()); + } + + if (stationsTakenByRobot.containsKey(robot.getRobotId())) { + HashSet stationSet = (HashSet) stationsTakenByRobot.get(robot.getRobotId()) + .clone(); + + for (StationIndex s : stationSet) { + DockingStation d = stations.get(s); + + if (!d.canRelease()) { + if (forceAll) { + d.unsafeRelease(robot); + } + } else { + d.unsafeRelease(robot); + } + } + + if (forceAll) { + stationsTakenByRobot.remove(robot.getRobotId()); + } + } + } + + public DockingStation getStation(int x, int y, int z, ForgeDirection side) { + StationIndex index = new StationIndex(side, x, y, z); + + if (stations.containsKey(index)) { + return stations.get(index); + } else { + return null; + } + } + + public Collection getStations() { + return stations.values(); + } + + public void registerStation(DockingStation station) { + markDirty(); + + StationIndex index = new StationIndex(station); + + if (stations.containsKey(index)) { + throw new InvalidParameterException("Station " + index + " already registerd"); + } else { + stations.put(index, station); + } + } + + public void removeStation(DockingStation station) { + markDirty(); + + StationIndex index = new StationIndex(station); + + if (stations.containsKey(index)) { + if (station.robotTaking() != null) { + station.robotTaking().setDead(); + } + + stations.remove(index); + } + } + + public void take(DockingStation station, long robotId) { + if (!stationsTakenByRobot.containsKey(robotId)) { + stationsTakenByRobot.put(robotId, new HashSet()); + } + + stationsTakenByRobot.get(robotId).add(new StationIndex(station)); + } + + public void release(DockingStation station, long robotId) { + if (stationsTakenByRobot.containsKey(robotId)) { + stationsTakenByRobot.get(robotId).remove(new StationIndex(station)); + } + } + + public static RobotRegistry getRegistry (World world) { + if (registries[world.provider.dimensionId] == null + || registries[world.provider.dimensionId].world != world) { + + RobotRegistry newRegistry = (RobotRegistry) world.perWorldStorage.loadData(RobotRegistry.class, "robotRegistry"); + + if (newRegistry == null) { + newRegistry = new RobotRegistry("robotRegistry"); + world.perWorldStorage.setData("robotRegistry", newRegistry); + } + + newRegistry.world = world; + + for (DockingStation d : newRegistry.stations.values()) { + d.world = world; + } + + registries[world.provider.dimensionId] = newRegistry; + } + + return registries[world.provider.dimensionId]; + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + nbt.setLong("nextRobotID", nextRobotID); + + NBTTagList resourceList = new NBTTagList(); + + for (Map.Entry e : resourcesTaken.entrySet()) { + NBTTagCompound cpt = new NBTTagCompound(); + NBTTagCompound resourceId = new NBTTagCompound(); + e.getKey().writeToNBT(resourceId); + cpt.setTag("resourceId", resourceId); + cpt.setLong("robotId", e.getValue()); + + resourceList.appendTag(cpt); + } + + nbt.setTag("resourceList", resourceList); + + NBTTagList stationList = new NBTTagList(); + + for (Map.Entry e : stations.entrySet()) { + NBTTagCompound cpt = new NBTTagCompound(); + e.getValue().writeToNBT(cpt); + stationList.appendTag(cpt); + } + + nbt.setTag("stationList", stationList); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + nextRobotID = nbt.getLong("nextRobotID"); + + NBTTagList resourceList = nbt.getTagList("resourceList", Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < resourceList.tagCount(); ++i) { + NBTTagCompound cpt = resourceList.getCompoundTagAt(i); + ResourceId resourceId = ResourceId.load(cpt.getCompoundTag("resourceId")); + long robotId = cpt.getLong("robotId"); + + take(resourceId, robotId); + } + + NBTTagList stationList = nbt.getTagList("stationList", Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < stationList.tagCount(); ++i) { + NBTTagCompound cpt = stationList.getCompoundTagAt(i); + DockingStation station = new DockingStation(); + station.readFromNBT(cpt); + + registerStation(station); + + if (station.linkedId() != EntityRobotBase.NULL_ROBOT_ID) { + take(station, station.linkedId()); + } + } + } +} diff --git a/common/buildcraft/core/robots/RobotTaskProviderRegistry.java b/common/buildcraft/core/robots/RobotTaskProviderRegistry.java deleted file mode 100755 index 0abf8ec3..00000000 --- a/common/buildcraft/core/robots/RobotTaskProviderRegistry.java +++ /dev/null @@ -1,66 +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.core.robots; - -import java.util.ArrayList; -import java.util.Collections; - -public final class RobotTaskProviderRegistry { - - public static int callNb = 0; - - private static ArrayList providers = new ArrayList(); - - /** - * Deactivate constructor - */ - private RobotTaskProviderRegistry() { - } - - public static void registerProvider (IRobotTaskProvider provider) { - providers.add(provider); - } - - public static void scanForTask (EntityRobot robot) { - callNb++; - - if (callNb >= 31 /*prime number, could be bigger */) { - Collections.shuffle (providers); - } - - for (int i = providers.size() - 1; i >= 0; --i) { - if (!providers.get(i).isActive()) { - providers.remove(i); - } else { - IRobotTaskProvider provider = providers.get(i); - - if (provider.getWorld() == robot.worldObj) { - double dx = robot.posX - provider.getX(); - double dy = robot.posY - provider.getY(); - double dz = robot.posZ - provider.getZ(); - - // TODO: 30 blocks is the current magic constant for robot - // task scan. Could be variable instead. - if (dx * dx + dy * dy + dz * dz < 30 * 30) { - IRobotTask task = provider.getNextTask(robot); - - if (task != null && robot.acceptTask(task)) { - // robot.currentTask = task; - task.setup(robot); - provider.popNextTask(); - - return; - } - } - } - } - } - } - -} diff --git a/common/buildcraft/core/robots/StationIndex.java b/common/buildcraft/core/robots/StationIndex.java new file mode 100755 index 00000000..63ba59bb --- /dev/null +++ b/common/buildcraft/core/robots/StationIndex.java @@ -0,0 +1,63 @@ +/** + * 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.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.core.BlockIndex; + +public class StationIndex { + + public BlockIndex index = new BlockIndex(); + public ForgeDirection side = ForgeDirection.UNKNOWN; + + protected StationIndex() { + } + + public StationIndex(ForgeDirection iSide, int x, int y, int z) { + side = iSide; + index = new BlockIndex(x, y, z); + } + + public StationIndex(DockingStation station) { + side = station.side; + index = station.index(); + } + + @Override + public boolean equals(Object obj) { + if (obj.getClass() != getClass()) { + return false; + } + + StationIndex compareId = (StationIndex) obj; + + return index.equals(compareId.index) + && side == compareId.side; + } + + @Override + public int hashCode() { + return (index.hashCode() * 37) + side.ordinal(); + } + + public void writeToNBT(NBTTagCompound nbt) { + NBTTagCompound indexNBT = new NBTTagCompound(); + index.writeTo(indexNBT); + nbt.setTag("index", indexNBT); + nbt.setByte("side", (byte) side.ordinal()); + } + + protected void readFromNBT(NBTTagCompound nbt) { + index = new BlockIndex(nbt.getCompoundTag("index")); + side = ForgeDirection.values()[nbt.getByte("side")]; + } +} diff --git a/common/buildcraft/core/robots/boards/BoardRobotCrafter.java b/common/buildcraft/core/robots/boards/BoardRobotCrafter.java index 290f42a4..23ed1ff9 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotCrafter.java +++ b/common/buildcraft/core/robots/boards/BoardRobotCrafter.java @@ -35,7 +35,6 @@ import buildcraft.core.robots.AIRobotCraftGeneric; import buildcraft.core.robots.AIRobotCraftWorkbench; import buildcraft.core.robots.AIRobotGotoSleep; import buildcraft.core.robots.AIRobotGotoStationToUnload; -import buildcraft.core.robots.AIRobotSleep; import buildcraft.core.robots.AIRobotUnload; import buildcraft.core.robots.DockingStation; import buildcraft.silicon.statements.ActionRobotCraft; @@ -73,7 +72,7 @@ public class BoardRobotCrafter extends RedstoneBoardRobot { if (order == null) { craftingBlacklist.clear(); - startDelegateAI(new AIRobotSleep(robot)); + startDelegateAI(new AIRobotGotoSleep(robot)); return; } @@ -169,7 +168,7 @@ public class BoardRobotCrafter extends RedstoneBoardRobot { DockingStation s = (DockingStation) robot.getLinkedStation(); - for (ActionSlot slot : new ActionIterator(s.pipe.pipe)) { + for (ActionSlot slot : new ActionIterator(s.getPipe().pipe)) { if (slot.action instanceof ActionRobotCraft) { for (IActionParameter p : slot.parameters) { if (p != null && p instanceof ActionParameterItemStack) { diff --git a/common/buildcraft/core/robots/boards/BoardRobotFarmer.java b/common/buildcraft/core/robots/boards/BoardRobotFarmer.java index f93b4678..7301031f 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotFarmer.java +++ b/common/buildcraft/core/robots/boards/BoardRobotFarmer.java @@ -27,6 +27,8 @@ import buildcraft.core.robots.AIRobotGotoSleep; import buildcraft.core.robots.AIRobotSearchBlock; import buildcraft.core.robots.AIRobotUseToolOnBlock; import buildcraft.core.robots.IBlockFilter; +import buildcraft.core.robots.ResourceIdBlock; +import buildcraft.core.robots.RobotRegistry; public class BoardRobotFarmer extends RedstoneBoardRobot { @@ -55,7 +57,7 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { @Override public boolean matches(World world, int x, int y, int z) { return BuildCraftAPI.isDirtProperty.get(world, x, y, z) - && RedstoneBoardRobot.isFreeBlock(new BlockIndex(x, y, z)) + && robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z)) && isAirAbove(world, x, y, z); } })); @@ -67,9 +69,12 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { if (ai instanceof AIRobotSearchBlock) { AIRobotSearchBlock searchAI = (AIRobotSearchBlock) ai; - if (searchAI.blockFound != null && RedstoneBoardRobot.reserveBlock(searchAI.blockFound)) { + if (searchAI.blockFound != null + && RobotRegistry.getRegistry(robot.worldObj).take( + new ResourceIdBlock(searchAI.blockFound), robot)) { + if (blockFound != null) { - RedstoneBoardRobot.releaseBlock(blockFound); + robot.getRegistry().release(new ResourceIdBlock(blockFound)); } blockFound = searchAI.blockFound; @@ -86,7 +91,7 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { startDelegateAI(new AIRobotGotoSleep(robot)); } } else if (ai instanceof AIRobotUseToolOnBlock) { - RedstoneBoardRobot.releaseBlock(blockFound); + robot.getRegistry().release(new ResourceIdBlock(blockFound)); blockFound = null; } } @@ -94,7 +99,7 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { @Override public void end() { if (blockFound != null) { - RedstoneBoardRobot.releaseBlock(blockFound); + robot.getRegistry().release(new ResourceIdBlock(blockFound)); } } @@ -115,10 +120,6 @@ public class BoardRobotFarmer extends RedstoneBoardRobot { if (nbt.hasKey("blockFound")) { blockFound = new BlockIndex(nbt.getCompoundTag("blockFound")); - - if (!RedstoneBoardRobot.reserveBlock(blockFound)) { - blockFound = null; - } } } diff --git a/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java b/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java index 68d12fac..8aebb7fb 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java +++ b/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java @@ -31,6 +31,7 @@ import buildcraft.core.robots.AIRobotGotoSleep; import buildcraft.core.robots.AIRobotSearchBlock; import buildcraft.core.robots.DockingStation; import buildcraft.core.robots.IBlockFilter; +import buildcraft.core.robots.ResourceIdBlock; import buildcraft.silicon.statements.ActionRobotFilter; import buildcraft.transport.gates.ActionIterator; import buildcraft.transport.gates.ActionSlot; @@ -58,7 +59,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { public final void start() { DockingStation station = (DockingStation) robot.getLinkedStation(); - for (ActionSlot slot : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot slot : new ActionIterator(station.getPipe().pipe)) { if (slot.action instanceof ActionRobotFilter) { for (IActionParameter p : slot.parameters) { if (p != null && p instanceof ActionParameterItemStack) { @@ -79,7 +80,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { if (ai instanceof AIRobotSearchBlock) { BlockIndex index = ((AIRobotSearchBlock) ai).blockFound; - if (!RedstoneBoardRobot.isFreeBlock(index)) { + if (!robot.getRegistry().isTaken(new ResourceIdBlock(index))) { abortDelegateAI(); } } @@ -99,7 +100,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { @Override public boolean matches(World world, int x, int y, int z) { if (isExpectedBlock(world, x, y, z) && matchesGateFilter(world, x, y, z)) { - return RedstoneBoardRobot.isFreeBlock(new BlockIndex(x, y, z)); + return robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z)); } else { return false; } @@ -112,7 +113,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { public void delegateAIEnded(AIRobot ai) { if (ai instanceof AIRobotSearchBlock) { if (indexStored != null) { - RedstoneBoardRobot.releaseBlock(indexStored); + robot.getRegistry().release(new ResourceIdBlock(indexStored)); } indexStored = ((AIRobotSearchBlock) ai).blockFound; @@ -120,14 +121,14 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { if (indexStored == null) { startDelegateAI(new AIRobotGotoSleep(robot)); } else { - if (reserveBlock(indexStored)) { + if (robot.getRegistry().take(new ResourceIdBlock(indexStored), robot)) { startDelegateAI(new AIRobotGotoBlock(robot, ((AIRobotSearchBlock) ai).path)); } } } else if (ai instanceof AIRobotGotoBlock) { startDelegateAI(new AIRobotBreak(robot, indexStored)); } else if (ai instanceof AIRobotBreak) { - releaseBlock(indexStored); + robot.getRegistry().release(new ResourceIdBlock(indexStored)); indexStored = null; } } @@ -135,7 +136,7 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { @Override public void end() { if (indexStored != null) { - releaseBlock(indexStored); + robot.getRegistry().release(new ResourceIdBlock(indexStored)); } } @@ -182,10 +183,6 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { if (nbt.hasKey("indexStored")) { indexStored = new BlockIndex (nbt.getCompoundTag("indexStored")); - - if (!reserveBlock(indexStored)) { - indexStored = null; - } } } } diff --git a/common/buildcraft/core/robots/boards/BoardRobotPlanter.java b/common/buildcraft/core/robots/boards/BoardRobotPlanter.java index f61f2e7a..665814d0 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotPlanter.java +++ b/common/buildcraft/core/robots/boards/BoardRobotPlanter.java @@ -37,6 +37,7 @@ import buildcraft.core.robots.AIRobotGotoSleep; import buildcraft.core.robots.AIRobotSearchBlock; import buildcraft.core.robots.AIRobotUseToolOnBlock; import buildcraft.core.robots.IBlockFilter; +import buildcraft.core.robots.ResourceIdBlock; import buildcraft.silicon.statements.ActionRobotFilter; public class BoardRobotPlanter extends RedstoneBoardRobot { @@ -85,7 +86,7 @@ public class BoardRobotPlanter extends RedstoneBoardRobot { @Override public boolean matches(World world, int x, int y, int z) { return BuildCraftAPI.isFarmlandProperty.get(world, x, y, z) - && RedstoneBoardRobot.isFreeBlock(new BlockIndex(x, y, z)) + && robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z)) && isAirAbove(world, x, y, z); } })); @@ -115,9 +116,11 @@ public class BoardRobotPlanter extends RedstoneBoardRobot { } else if (ai instanceof AIRobotSearchBlock) { AIRobotSearchBlock gotoBlock = (AIRobotSearchBlock) ai; - if (gotoBlock.blockFound != null && RedstoneBoardRobot.reserveBlock(gotoBlock.blockFound)) { + if (gotoBlock.blockFound != null + && robot.getRegistry().take(new ResourceIdBlock(gotoBlock.blockFound), robot)) { + if (blockFound != null) { - RedstoneBoardRobot.releaseBlock(blockFound); + robot.getRegistry().release(new ResourceIdBlock(blockFound)); } blockFound = gotoBlock.blockFound; @@ -171,10 +174,6 @@ public class BoardRobotPlanter extends RedstoneBoardRobot { if (nbt.hasKey("blockFound")) { blockFound = new BlockIndex(nbt.getCompoundTag("blockFound")); - - if (!RedstoneBoardRobot.reserveBlock(blockFound)) { - blockFound = null; - } } } } diff --git a/common/buildcraft/silicon/statements/ActionRobotFilter.java b/common/buildcraft/silicon/statements/ActionRobotFilter.java index 96f28cec..a203bee8 100755 --- a/common/buildcraft/silicon/statements/ActionRobotFilter.java +++ b/common/buildcraft/silicon/statements/ActionRobotFilter.java @@ -60,7 +60,7 @@ public class ActionRobotFilter extends BCActionPassive { public static Collection getGateFilterStacks(IDockingStation station) { ArrayList result = new ArrayList(); - for (ActionSlot slot : new ActionIterator(((DockingStation) station).pipe.pipe)) { + for (ActionSlot slot : new ActionIterator(((DockingStation) station).getPipe().pipe)) { if (slot.action instanceof ActionRobotFilter) { for (IActionParameter p : slot.parameters) { if (p != null && p instanceof ActionParameterItemStack) { diff --git a/common/buildcraft/silicon/statements/ActionRobotGotoStation.java b/common/buildcraft/silicon/statements/ActionRobotGotoStation.java index 74a15f5d..d80598f6 100755 --- a/common/buildcraft/silicon/statements/ActionRobotGotoStation.java +++ b/common/buildcraft/silicon/statements/ActionRobotGotoStation.java @@ -18,11 +18,11 @@ import buildcraft.api.gates.ActionParameterItemStack; import buildcraft.api.gates.IActionParameter; import buildcraft.api.gates.IGate; import buildcraft.api.robots.AIRobot; -import buildcraft.api.robots.DockingStationRegistry; import buildcraft.core.ItemMapLocation; import buildcraft.core.robots.AIRobotGoAndLinkToDock; import buildcraft.core.robots.DockingStation; import buildcraft.core.robots.EntityRobot; +import buildcraft.core.robots.RobotRegistry; import buildcraft.core.triggers.BCActionActive; import buildcraft.core.utils.StringUtils; import buildcraft.transport.Pipe; @@ -48,12 +48,13 @@ public class ActionRobotGotoStation extends BCActionActive { public void actionActivate(IGate gate, IActionParameter[] parameters) { Pipe pipe = (Pipe) gate.getPipe(); TileGenericPipe tile = pipe.container; + RobotRegistry registry = RobotRegistry.getRegistry(pipe.getWorld()); for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS) { DockingStation station = tile.getStation(d); - if (station != null && station.linked() != null) { - EntityRobot robot = (EntityRobot) station.linked(); + if (station != null && station.robotTaking() != null) { + EntityRobot robot = (EntityRobot) station.robotTaking(); AIRobot ai = robot.getOverridingAI(); if (ai != null) { @@ -71,7 +72,7 @@ public class ActionRobotGotoStation extends BCActionActive { if (index != null) { ForgeDirection side = ItemMapLocation.getSide(item); - DockingStation paramStation = (DockingStation) DockingStationRegistry.getStation(index.x, + DockingStation paramStation = registry.getStation(index.x, index.y, index.z, side); if (paramStation != null) { diff --git a/common/buildcraft/silicon/statements/ActionStationForbidRobot.java b/common/buildcraft/silicon/statements/ActionStationForbidRobot.java index bf7fbac9..38498c3d 100755 --- a/common/buildcraft/silicon/statements/ActionStationForbidRobot.java +++ b/common/buildcraft/silicon/statements/ActionStationForbidRobot.java @@ -53,7 +53,7 @@ public class ActionStationForbidRobot extends BCActionPassive { } public static boolean isForbidden(DockingStation station, EntityRobotBase robot) { - for (ActionSlot s : new ActionIterator(station.pipe.pipe)) { + for (ActionSlot s : new ActionIterator(station.getPipe().pipe)) { if (s.action instanceof ActionStationForbidRobot) { if (ActionStationForbidRobot.isForbidden(s, robot)) { return true; diff --git a/common/buildcraft/silicon/statements/ActionStationRequestItemsPipe.java b/common/buildcraft/silicon/statements/ActionStationRequestItemsPipe.java index d6a2b2dd..59ba4fe1 100755 --- a/common/buildcraft/silicon/statements/ActionStationRequestItemsPipe.java +++ b/common/buildcraft/silicon/statements/ActionStationRequestItemsPipe.java @@ -57,14 +57,14 @@ public class ActionStationRequestItemsPipe extends ActionStationRequestItems { return true; } - if (station.pipe.pipe.transport instanceof PipeTransportItems) { + if (station.getPipe().pipe.transport instanceof PipeTransportItems) { float cx = station.x() + 0.5F + 0.2F * station.side().offsetX; float cy = station.y() + 0.5F + 0.2F * station.side().offsetY; float cz = station.z() + 0.5F + 0.2F * station.side().offsetZ; TravelingItem item = TravelingItem.make(cx, cy, cz, invSlot.getStackInSlot()); - ((PipeTransportItems) station.pipe.pipe.transport).injectItem(item, station.side().getOpposite()); + ((PipeTransportItems) station.getPipe().pipe.transport).injectItem(item, station.side().getOpposite()); invSlot.setStackInSlot(null); diff --git a/common/buildcraft/silicon/statements/RobotsActionProvider.java b/common/buildcraft/silicon/statements/RobotsActionProvider.java index ceaaf40f..7282e637 100755 --- a/common/buildcraft/silicon/statements/RobotsActionProvider.java +++ b/common/buildcraft/silicon/statements/RobotsActionProvider.java @@ -52,7 +52,7 @@ public class RobotsActionProvider implements IActionProvider { result.add(BuildCraftSilicon.actionStationForbidRobot); for (DockingStation s : stations) { - if (s.linked() != null && s.linked().getBoard() instanceof BoardRobotCrafter) { + if (s.robotTaking() != null && s.robotTaking().getBoard() instanceof BoardRobotCrafter) { result.add(BuildCraftSilicon.actionRobotCraft); } } diff --git a/common/buildcraft/silicon/statements/TriggerRobotSleep.java b/common/buildcraft/silicon/statements/TriggerRobotSleep.java index 6fedccc3..981caa58 100755 --- a/common/buildcraft/silicon/statements/TriggerRobotSleep.java +++ b/common/buildcraft/silicon/statements/TriggerRobotSleep.java @@ -46,8 +46,8 @@ public class TriggerRobotSleep extends BCTrigger { for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS) { DockingStation station = tile.getStation(d); - if (station != null && station.linked() != null) { - EntityRobot robot = (EntityRobot) station.linked(); + if (station != null && station.robotTaking() != null) { + EntityRobot robot = (EntityRobot) station.robotTaking(); if (robot.mainAI.getActiveAI() instanceof AIRobotSleep) { return true; diff --git a/common/buildcraft/transport/BlockGenericPipe.java b/common/buildcraft/transport/BlockGenericPipe.java index f0da3d74..3fd9249b 100644 --- a/common/buildcraft/transport/BlockGenericPipe.java +++ b/common/buildcraft/transport/BlockGenericPipe.java @@ -74,9 +74,9 @@ public class BlockGenericPipe extends BlockBuildCraft { public static Map> pipeRemoved = new HashMap>(); private static long lastRemovedDate = -1; - + private static final ForgeDirection[] DIR_VALUES = ForgeDirection.values(); - + static enum Part { Pipe, Gate, @@ -84,7 +84,7 @@ public class BlockGenericPipe extends BlockBuildCraft { Plug, RobotStation } - + static class RaytraceResult { public final Part hitPart; public final MovingObjectPosition movingObjectPosition; @@ -103,7 +103,7 @@ public class BlockGenericPipe extends BlockBuildCraft { return String.format("RayTraceResult: %s, %s", hitPart == null ? "null" : hitPart.name(), boundingBox == null ? "null" : boundingBox.toString()); } } - + private boolean skippedFirstIconRegister; /* Defined subprograms ************************************************* */ @@ -138,11 +138,11 @@ public class BlockGenericPipe extends BlockBuildCraft { public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; - } + } @Override public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z) { @@ -779,9 +779,10 @@ public class BlockGenericPipe extends BlockBuildCraft { if (rayTraceResult != null && rayTraceResult.hitPart == Part.RobotStation) { DockingStation station = pipe.container.getStation(rayTraceResult.sideHit); - if (station.linked() == null && station.reserved() == null) { + if (!station.isTaken()) { EntityRobot robot = ((ItemRobot) currentItem.getItem()) .createRobot(currentItem, world); + robot.setUniqueRobotId(robot.getRegistry().getNextRobotId()); robot.setEnergy(EntityRobot.MAX_ENERGY); float px = x + 0.5F + rayTraceResult.sideHit.offsetX * 0.5F; @@ -789,7 +790,7 @@ public class BlockGenericPipe extends BlockBuildCraft { float pz = z + 0.5F + rayTraceResult.sideHit.offsetZ * 0.5F; robot.setPosition(px, py, pz); - robot.linkToStation(station); + station.takeAsMain(robot); robot.dock(robot.getLinkedStation()); world.spawnEntityInWorld(robot); @@ -1007,8 +1008,8 @@ public class BlockGenericPipe extends BlockBuildCraft { private void dropWire(PipeWire pipeWire, Pipe pipe) { pipe.dropItem(pipeWire.getStack()); } - - + + @Override public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) { super.onEntityCollidedWithBlock(world, i, j, k, entity); diff --git a/common/buildcraft/transport/ItemRobotStation.java b/common/buildcraft/transport/ItemRobotStation.java index e258b1fd..117ba38f 100755 --- a/common/buildcraft/transport/ItemRobotStation.java +++ b/common/buildcraft/transport/ItemRobotStation.java @@ -20,12 +20,12 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftTransport; -import buildcraft.api.robots.DockingStationRegistry; import buildcraft.api.transport.IPipePluggable; import buildcraft.api.transport.IPipeTile; import buildcraft.core.CreativeTabBuildCraft; import buildcraft.core.ItemBuildCraft; import buildcraft.core.robots.DockingStation; +import buildcraft.core.robots.RobotRegistry; public class ItemRobotStation extends ItemBuildCraft { @@ -99,20 +99,27 @@ public class ItemRobotStation extends ItemBuildCraft { @Override public void invalidate() { - if (station != null && !station.pipe.getWorld().isRemote) { - DockingStationRegistry.removeStation(station); + if (station != null && !station.getPipe().getWorld().isRemote) { + RobotRegistry.getRegistry(station.world).removeStation(station); isValid = false; } } @Override public void validate(IPipeTile pipe, ForgeDirection direction) { - if (!isValid && !((TileGenericPipe) pipe).getWorld().isRemote) { + TileGenericPipe gPipe = (TileGenericPipe) pipe; + if (!isValid && !gPipe.getWorld().isRemote) { + station = RobotRegistry.getRegistry(gPipe.getWorld()).getStation( + gPipe.xCoord, + gPipe.yCoord, + gPipe.zCoord, + direction); + if (station == null) { - station = new DockingStation((TileGenericPipe) pipe, direction); + station = new DockingStation(gPipe, direction); + RobotRegistry.getRegistry(gPipe.getWorld()).registerStation(station); } - DockingStationRegistry.registerStation(station); isValid = true; } } diff --git a/common/buildcraft/transport/TileGenericPipe.java b/common/buildcraft/transport/TileGenericPipe.java index b157ba5a..a8719fa6 100755 --- a/common/buildcraft/transport/TileGenericPipe.java +++ b/common/buildcraft/transport/TileGenericPipe.java @@ -507,12 +507,14 @@ public class TileGenericPipe extends TileEntity implements IPowerReceptor, IFlui if (pluggable instanceof ItemRobotStation.RobotStationPluggable) { DockingStation station = ((ItemRobotStation.RobotStationPluggable) pluggable).getStation(); - if (station.linked() != null) { - renderState.robotStationMatrix.setState(direction, + if (station.isTaken()) { + if (station.isMainStation()) { + renderState.robotStationMatrix.setState(direction, RobotStationState.Linked); - } else if (station.reserved() != null) { - renderState.robotStationMatrix.setState(direction, - RobotStationState.Reserved); + } else { + renderState.robotStationMatrix.setState(direction, + RobotStationState.Reserved); + } } else { renderState.robotStationMatrix.setState(direction, RobotStationState.Available);