diff --git a/api/buildcraft/api/core/BuildCraftAPI.java b/api/buildcraft/api/core/BuildCraftAPI.java index 5b788a6e..736382b9 100644 --- a/api/buildcraft/api/core/BuildCraftAPI.java +++ b/api/buildcraft/api/core/BuildCraftAPI.java @@ -29,6 +29,7 @@ public final class BuildCraftAPI { public static IWorldProperty isFarmlandProperty; public static IWorldProperty isDirtProperty; public static IWorldProperty isShoveled; + public static IWorldProperty isFluidSource; /** * Deactivate constructor diff --git a/buildcraft_resources/assets/buildcraft/lang/en_US.lang b/buildcraft_resources/assets/buildcraft/lang/en_US.lang index 686f67c5..78735130 100755 --- a/buildcraft_resources/assets/buildcraft/lang/en_US.lang +++ b/buildcraft_resources/assets/buildcraft/lang/en_US.lang @@ -16,6 +16,7 @@ buildcraft.boardRobotButcher=Butcher buildcraft.boardRobotBuilder=Builder buildcraft.boardRobotCrafter=Crafter buildcraft.boardRobotDelivery=Delivery +buildcraft.boardRobotPump=Pump chat.pipe.power.iron.mode=Switched to %d MJ/t limit chat.pipe.power.energyConverter=Energy conversion: %s diff --git a/common/buildcraft/BuildCraftCore.java b/common/buildcraft/BuildCraftCore.java index d7f400e0..8fe09a9a 100644 --- a/common/buildcraft/BuildCraftCore.java +++ b/common/buildcraft/BuildCraftCore.java @@ -115,6 +115,7 @@ import buildcraft.core.triggers.TriggerRedstoneInput; import buildcraft.core.utils.CraftingHandler; import buildcraft.core.utils.WorldPropertyIsDirt; import buildcraft.core.utils.WorldPropertyIsFarmland; +import buildcraft.core.utils.WorldPropertyIsFluidSource; import buildcraft.core.utils.WorldPropertyIsHarvestable; import buildcraft.core.utils.WorldPropertyIsLeave; import buildcraft.core.utils.WorldPropertyIsOre; @@ -418,6 +419,7 @@ public class BuildCraftCore extends BuildCraftMod { BuildCraftAPI.isFarmlandProperty = new WorldPropertyIsFarmland(); BuildCraftAPI.isShoveled = new WorldPropertyIsShoveled(); BuildCraftAPI.isDirtProperty = new WorldPropertyIsDirt(); + BuildCraftAPI.isFluidSource = new WorldPropertyIsFluidSource(); } @Mod.EventHandler diff --git a/common/buildcraft/BuildCraftSilicon.java b/common/buildcraft/BuildCraftSilicon.java index d815dea6..176b0376 100644 --- a/common/buildcraft/BuildCraftSilicon.java +++ b/common/buildcraft/BuildCraftSilicon.java @@ -62,6 +62,7 @@ import buildcraft.core.robots.boards.BoardRobotLumberjackNBT; import buildcraft.core.robots.boards.BoardRobotMinerNBT; import buildcraft.core.robots.boards.BoardRobotPickerNBT; import buildcraft.core.robots.boards.BoardRobotPlanterNBT; +import buildcraft.core.robots.boards.BoardRobotPumpNBT; import buildcraft.core.robots.boards.BoardRobotShovelmanNBT; import buildcraft.core.science.TechnoRobot; import buildcraft.core.science.TechnoSimpleItem; @@ -226,6 +227,7 @@ public class BuildCraftSilicon extends BuildCraftMod { RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotShovelmanNBT.instance, 5); RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotCrafterNBT.instance, 5); RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotDeliveryNBT.instance, 5); + RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotPumpNBT.instance, 5); RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotKnightNBT.instance, 1); RedstoneBoardRegistry.instance.registerBoardClass(BoardRobotBomberNBT.instance, 1); diff --git a/common/buildcraft/core/robots/AIRobotPumpBlock.java b/common/buildcraft/core/robots/AIRobotPumpBlock.java new file mode 100755 index 00000000..f3094bd8 --- /dev/null +++ b/common/buildcraft/core/robots/AIRobotPumpBlock.java @@ -0,0 +1,78 @@ +/** + * 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.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.core.BlockIndex; +import buildcraft.api.robots.AIRobot; +import buildcraft.api.robots.EntityRobotBase; + +public class AIRobotPumpBlock extends AIRobot { + + public BlockIndex blockToPump; + public long waited = 0; + int pumped = 0; + + public AIRobotPumpBlock(EntityRobotBase iRobot) { + super(iRobot); + } + + public AIRobotPumpBlock(EntityRobotBase iRobot, BlockIndex iBlockToPump) { + super(iRobot); + + blockToPump = iBlockToPump; + } + + @Override + public void start() { + robot.aimItemAt(blockToPump.x, blockToPump.y, blockToPump.z); + } + + @Override + public void update() { + if (waited < 40) { + waited++; + } else { + Fluid fluid = FluidRegistry.lookupFluidForBlock(robot.worldObj.getBlock(blockToPump.x, blockToPump.y, + blockToPump.z)); + + if (fluid != null) { + pumped = robot.fill(ForgeDirection.UNKNOWN, + new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME), true); + + if (pumped > 0) { + robot.worldObj.setBlockToAir(blockToPump.x, blockToPump.y, blockToPump.z); + } + } + + terminate(); + } + + } + + @Override + public void end() { + robot.aimItemAt(0, 1, 0); + } + + @Override + public double getEnergyCost() { + return 2; + } + + @Override + public boolean success() { + return pumped > 0; + } +} diff --git a/common/buildcraft/core/robots/RobotRegistry.java b/common/buildcraft/core/robots/RobotRegistry.java index 0e9499eb..0d5e61a8 100755 --- a/common/buildcraft/core/robots/RobotRegistry.java +++ b/common/buildcraft/core/robots/RobotRegistry.java @@ -84,12 +84,12 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public boolean isTaken(ResourceId resourceId) { + public synchronized boolean isTaken(ResourceId resourceId) { return robotIdTaking(resourceId) != EntityRobotBase.NULL_ROBOT_ID; } @Override - public long robotIdTaking(ResourceId resourceId) { + public synchronized long robotIdTaking(ResourceId resourceId) { if (!resourcesTaken.containsKey(resourceId)) { return EntityRobotBase.NULL_ROBOT_ID; } @@ -107,7 +107,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public EntityRobot robotTaking(ResourceId resourceId) { + public synchronized EntityRobot robotTaking(ResourceId resourceId) { long robotId = robotIdTaking(resourceId); if (robotId == EntityRobotBase.NULL_ROBOT_ID || !robotsLoaded.containsKey(robotId)) { @@ -118,14 +118,14 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public boolean take(ResourceId resourceId, EntityRobotBase robot) { + public synchronized boolean take(ResourceId resourceId, EntityRobotBase robot) { markDirty(); return take(resourceId, robot.getRobotId()); } @Override - public boolean take(ResourceId resourceId, long robotId) { + public synchronized boolean take(ResourceId resourceId, long robotId) { if (resourceId == null) { return false; } @@ -150,7 +150,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void release(ResourceId resourceId) { + public synchronized void release(ResourceId resourceId) { if (resourceId == null) { return; } @@ -167,11 +167,11 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void releaseResources(EntityRobotBase robot) { + public synchronized void releaseResources(EntityRobotBase robot) { releaseResources(robot, false); } - private void releaseResources(EntityRobotBase robot, boolean forceAll) { + private synchronized void releaseResources(EntityRobotBase robot, boolean forceAll) { markDirty(); if (resourcesTakenByRobot.containsKey(robot.getRobotId())) { @@ -210,7 +210,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public IDockingStation getStation(int x, int y, int z, ForgeDirection side) { + public synchronized IDockingStation getStation(int x, int y, int z, ForgeDirection side) { StationIndex index = new StationIndex(side, x, y, z); if (stations.containsKey(index)) { @@ -221,12 +221,12 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public Collection getStations() { + public synchronized Collection getStations() { return stations.values(); } @Override - public void registerStation(IDockingStation station) { + public synchronized void registerStation(IDockingStation station) { markDirty(); StationIndex index = new StationIndex(station); @@ -239,7 +239,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void removeStation(IDockingStation station) { + public synchronized void removeStation(IDockingStation station) { markDirty(); StationIndex index = new StationIndex(station); @@ -254,7 +254,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void take(IDockingStation station, long robotId) { + public synchronized void take(IDockingStation station, long robotId) { if (!stationsTakenByRobot.containsKey(robotId)) { stationsTakenByRobot.put(robotId, new HashSet()); } @@ -263,13 +263,13 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void release(IDockingStation station, long robotId) { + public synchronized void release(IDockingStation station, long robotId) { if (stationsTakenByRobot.containsKey(robotId)) { stationsTakenByRobot.get(robotId).remove(new StationIndex(station)); } } - public static RobotRegistry getRegistry (World world) { + public static synchronized RobotRegistry getRegistry(World world) { if (registries[world.provider.dimensionId] == null || registries[world.provider.dimensionId].world != world) { @@ -293,7 +293,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void writeToNBT(NBTTagCompound nbt) { + public synchronized void writeToNBT(NBTTagCompound nbt) { nbt.setLong("nextRobotID", nextRobotID); NBTTagList resourceList = new NBTTagList(); @@ -322,7 +322,7 @@ public class RobotRegistry extends WorldSavedData implements IRobotRegistry { } @Override - public void readFromNBT(NBTTagCompound nbt) { + public synchronized void readFromNBT(NBTTagCompound nbt) { nextRobotID = nbt.getLong("nextRobotID"); NBTTagList resourceList = nbt.getTagList("resourceList", Constants.NBT.TAG_COMPOUND); diff --git a/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java b/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java index 41e144ab..c4de70d8 100755 --- a/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java +++ b/common/buildcraft/core/robots/boards/BoardRobotGenericBreakBlock.java @@ -55,27 +55,6 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { */ public abstract boolean isExpectedBlock(World world, int x, int y, int z); - @Override - public final void start() { - DockingStation station = (DockingStation) robot.getLinkedStation(); - - for (ActionSlot slot : new ActionIterator(station.getPipe().pipe)) { - if (slot.action instanceof ActionRobotFilter) { - for (IActionParameter p : slot.parameters) { - if (p != null && p instanceof ActionParameterItemStack) { - ActionParameterItemStack param = (ActionParameterItemStack) p; - ItemStack stack = param.getItemStackToDraw(); - - if (stack != null && stack.getItem() instanceof ItemBlock) { - blockFilter.add(((ItemBlock) stack.getItem()).field_150939_a); - metaFilter.add(stack.getItemDamage()); - } - } - } - } - } - } - public final void preemt(AIRobot ai) { if (ai instanceof AIRobotSearchBlock) { BlockIndex index = ((AIRobotSearchBlock) ai).blockFound; @@ -96,11 +75,13 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { } })); } else { + updateFilter(); + startDelegateAI(new AIRobotSearchBlock(robot, new IBlockFilter() { @Override public boolean matches(World world, int x, int y, int z) { - if (isExpectedBlock(world, x, y, z) && matchesGateFilter(world, x, y, z)) { - return !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z)); + if (isExpectedBlock(world, x, y, z) && !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))) { + return matchesGateFilter(world, x, y, z); } else { return false; } @@ -140,6 +121,29 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot { } } + public final void updateFilter() { + blockFilter.clear(); + metaFilter.clear(); + + DockingStation station = (DockingStation) robot.getLinkedStation(); + + for (ActionSlot slot : new ActionIterator(station.getPipe().pipe)) { + if (slot.action instanceof ActionRobotFilter) { + for (IActionParameter p : slot.parameters) { + if (p != null && p instanceof ActionParameterItemStack) { + ActionParameterItemStack param = (ActionParameterItemStack) p; + ItemStack stack = param.getItemStackToDraw(); + + if (stack != null && stack.getItem() instanceof ItemBlock) { + blockFilter.add(((ItemBlock) stack.getItem()).field_150939_a); + metaFilter.add(stack.getItemDamage()); + } + } + } + } + } + } + private boolean matchesGateFilter(World world, int x, int y, int z) { if (blockFilter.size() == 0) { return true; diff --git a/common/buildcraft/core/robots/boards/BoardRobotPump.java b/common/buildcraft/core/robots/boards/BoardRobotPump.java new file mode 100755 index 00000000..ef30e81a --- /dev/null +++ b/common/buildcraft/core/robots/boards/BoardRobotPump.java @@ -0,0 +1,163 @@ +/** + * 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.boards; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.boards.RedstoneBoardRobot; +import buildcraft.api.boards.RedstoneBoardRobotNBT; +import buildcraft.api.core.BlockIndex; +import buildcraft.api.core.BuildCraftAPI; +import buildcraft.api.gates.ActionParameterItemStack; +import buildcraft.api.gates.IActionParameter; +import buildcraft.api.robots.AIRobot; +import buildcraft.api.robots.EntityRobotBase; +import buildcraft.core.TickHandlerCore; +import buildcraft.core.robots.AIRobotGotoBlock; +import buildcraft.core.robots.AIRobotGotoSleep; +import buildcraft.core.robots.AIRobotGotoStationAndUnloadFluids; +import buildcraft.core.robots.AIRobotPumpBlock; +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; + +public class BoardRobotPump extends RedstoneBoardRobot { + + private BlockIndex blockFound; + private ArrayList fluidFilter = new ArrayList(); + + public BoardRobotPump(EntityRobotBase iRobot) { + super(iRobot); + } + + @Override + public RedstoneBoardRobotNBT getNBTHandler() { + return BoardRobotPumpNBT.instance; + } + + @Override + public void update() { + FluidStack tank = robot.getTankInfo(ForgeDirection.UNKNOWN)[0].fluid; + + if (tank != null && tank.amount > 0) { + startDelegateAI(new AIRobotGotoStationAndUnloadFluids(robot, robot.getZoneToWork())); + } else { + updateFilter(); + + startDelegateAI(new AIRobotSearchBlock(robot, new IBlockFilter() { + + @Override + public boolean matches(World world, int x, int y, int z) { + if (BuildCraftAPI.isFluidSource.get(world, x, y, z) + && !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))) { + return matchesGateFilter(world, x, y, z); + } else { + return false; + } + } + })); + } + } + + @Override + public void delegateAIEnded(AIRobot ai) { + if (ai instanceof AIRobotSearchBlock) { + if (!ai.success()) { + startDelegateAI(new AIRobotGotoSleep(robot)); + } else { + blockFound = ((AIRobotSearchBlock) ai).blockFound; + + if (!robot.getRegistry().take(new ResourceIdBlock (blockFound), robot)) { + blockFound = null; + startDelegateAI(new AIRobotGotoSleep(robot)); + } else { + startDelegateAI(new AIRobotGotoBlock(robot, ((AIRobotSearchBlock) ai).path)); + } + } + } else if (ai instanceof AIRobotGotoBlock) { + if (!ai.success()) { + startDelegateAI(new AIRobotGotoSleep(robot)); + } else { + startDelegateAI(new AIRobotPumpBlock(robot, blockFound)); + } + } else if (ai instanceof AIRobotGotoStationAndUnloadFluids) { + robot.getRegistry().take(new ResourceIdBlock (blockFound), robot); + + if (!ai.success()) { + startDelegateAI(new AIRobotGotoSleep(robot)); + } + } + } + + public void updateFilter() { + fluidFilter.clear(); + + DockingStation station = (DockingStation) robot.getLinkedStation(); + + for (ActionSlot slot : new ActionIterator(station.getPipe().pipe)) { + if (slot.action instanceof ActionRobotFilter) { + for (IActionParameter p : slot.parameters) { + if (p != null && p instanceof ActionParameterItemStack) { + ActionParameterItemStack param = (ActionParameterItemStack) p; + ItemStack stack = param.getItemStackToDraw(); + + if (stack != null) { + FluidStack fluid = FluidContainerRegistry.getFluidForFilledItem(stack); + + if (fluid != null) { + fluidFilter.add(fluid.getFluid()); + } + } + } + } + } + } + } + + private boolean matchesGateFilter(World world, int x, int y, int z) { + if (fluidFilter.size() == 0) { + return true; + } + + synchronized (TickHandlerCore.startSynchronousComputation) { + try { + TickHandlerCore.startSynchronousComputation.wait(); + + Block block = world.getBlock(x, y, z); + Fluid fluid = FluidRegistry.lookupFluidForBlock(block); + + for (Fluid f : fluidFilter) { + if (f.getID() == fluid.getID()) { + return true; + } + } + + return false; + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } + } + } + +} diff --git a/common/buildcraft/core/robots/boards/BoardRobotPumpNBT.java b/common/buildcraft/core/robots/boards/BoardRobotPumpNBT.java new file mode 100755 index 00000000..1af434c6 --- /dev/null +++ b/common/buildcraft/core/robots/boards/BoardRobotPumpNBT.java @@ -0,0 +1,64 @@ +/** + * 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.boards; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +import buildcraft.api.boards.RedstoneBoardRobot; +import buildcraft.api.boards.RedstoneBoardRobotNBT; +import buildcraft.api.robots.EntityRobotBase; +import buildcraft.core.DefaultProps; +import buildcraft.core.utils.StringUtils; + +public final class BoardRobotPumpNBT extends RedstoneBoardRobotNBT { + + public static BoardRobotPumpNBT instance = new BoardRobotPumpNBT(); + + private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", + DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_pump.png"); + + private IIcon icon; + + @Override + public RedstoneBoardRobot create(NBTTagCompound nbt, EntityRobotBase robot) { + return new BoardRobotPump(robot); + } + + @Override + public ResourceLocation getRobotTexture() { + return TEXTURE; + } + + @Override + public String getID() { + return "buildcraft:boardRobotPump"; + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean advanced) { + list.add(StringUtils.localize("buildcraft.boardRobotPump")); + } + + @Override + public void registerIcons(IIconRegister iconRegister) { + icon = iconRegister.registerIcon("buildcraft:board_blue"); + } + + @Override + public IIcon getIcon(NBTTagCompound nbt) { + return icon; + } +} diff --git a/common/buildcraft/core/utils/WorldPropertyIsFluidSource.java b/common/buildcraft/core/utils/WorldPropertyIsFluidSource.java new file mode 100755 index 00000000..efd48b86 --- /dev/null +++ b/common/buildcraft/core/utils/WorldPropertyIsFluidSource.java @@ -0,0 +1,24 @@ +/** + * 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.utils; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.world.IBlockAccess; + +import net.minecraftforge.fluids.BlockFluidBase; + +public class WorldPropertyIsFluidSource extends WorldProperty { + + @Override + public boolean get(IBlockAccess blockAccess, Block block, int meta, int x, int y, int z) { + return (block instanceof BlockLiquid || block instanceof BlockFluidBase) + && meta == 0; + } +}