add crop api

This commit is contained in:
Hea3veN 2015-05-25 12:41:52 -03:00
parent 633629792e
commit c3e0eeb3d0
13 changed files with 573 additions and 265 deletions

View file

@ -0,0 +1,57 @@
package buildcraft.api.crops;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class CropManager {
private static List<ICropHandler> handlers = new ArrayList<ICropHandler>();
public static void registerHandler(ICropHandler cropHandler) {
handlers.add(cropHandler);
}
public static boolean isSeed(ItemStack stack) {
for (ICropHandler cropHandler : handlers) {
if (cropHandler.isSeed(stack)) {
return true;
}
}
return false;
}
public static boolean canSustainPlant(World world, ItemStack seed, int x, int y, int z) {
for (ICropHandler cropHandler : handlers) {
if (cropHandler.isSeed(seed) && cropHandler.canSustainPlant(world, seed, x, y, z))
return true;
}
return false;
}
public static boolean isMature(IBlockAccess blockAccess, Block block, int meta, int x, int y,
int z) {
for (ICropHandler cropHandler : handlers) {
if (cropHandler.isMature(blockAccess, block, meta, x, y, z)) {
return true;
}
}
return false;
}
public static boolean harvestCrop(World world, int x, int y, int z, List<ItemStack> drops) {
for (ICropHandler cropHandler : handlers) {
Block block = world.getBlock(x, y, z);
int meta = world.getBlockMetadata(x, y, z);
if (cropHandler.isMature(world, block, meta, x, y, z)) {
return cropHandler.harvestCrop(world, x, y, z, drops);
}
}
return false;
}
}

View file

@ -0,0 +1,59 @@
package buildcraft.api.crops;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public interface ICropHandler {
/**
* Check if an item is a seed.
*
* @param stack
* @return true if the item can be planted.
*/
boolean isSeed(ItemStack stack);
/**
* Check if the item can be planted. You can assume canSustainPlant() will
* only be called if isSeed() returned true.
*
* @param world
* @param seed
* @param x
* @param y
* @param z
* @return true if the item can be planted at (x, y, z).
*/
boolean canSustainPlant(World world, ItemStack seed, int x, int y, int z);
/**
* Check if a crop is mature and can be harvested.
*
* @param blockAccess
* @param block
* @param meta
* @param x
* @param y
* @param z
* @return true if the block at (x, y, z) is mature and can be harvested.
*/
boolean isMature(IBlockAccess blockAccess, Block block, int meta, int x, int y, int z);
/**
* Harvest the crop. You can assume harvestCrop() will only be called if
* isMature() returned true.
*
* @param world
* @param x
* @param y
* @param z
* @param drops a list to return the harvest's drops.
* @return true if the block was successfully harvested.
*/
boolean harvestCrop(World world, int x, int y, int z, List<ItemStack> drops);
}

View file

@ -15,6 +15,7 @@ import java.nio.IntBuffer;
import java.util.UUID;
import com.mojang.authlib.GameProfile;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
@ -29,6 +30,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.Achievement;
import net.minecraft.util.IIcon;
import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
@ -42,6 +44,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.IPlantable;
@ -56,6 +59,7 @@ import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.core.EnumColor;
import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.IWorldProperty;
import buildcraft.api.crops.CropManager;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.api.statements.IActionExternal;
import buildcraft.api.statements.IActionInternal;
@ -93,6 +97,8 @@ import buildcraft.core.command.SubCommandChangelog;
import buildcraft.core.command.SubCommandVersion;
import buildcraft.core.config.BuildCraftConfiguration;
import buildcraft.core.config.ConfigManager;
import buildcraft.core.crops.CropHandlerPlantable;
import buildcraft.core.crops.CropHandlerReeds;
import buildcraft.core.lib.commands.RootCommand;
import buildcraft.core.lib.engines.ItemEngine;
import buildcraft.core.lib.engines.TileEngineBase;
@ -427,6 +433,9 @@ public class BuildCraftCore extends BuildCraftMod {
FMLCommonHandler.instance().bus().register(new TickHandlerCore());
CropManager.registerHandler(new CropHandlerPlantable());
CropManager.registerHandler(new CropHandlerReeds());
BuildCraftAPI.registerWorldProperty("soft", new WorldPropertyIsSoft());
BuildCraftAPI.registerWorldProperty("wood", new WorldPropertyIsWood());
BuildCraftAPI.registerWorldProperty("leaves", new WorldPropertyIsLeaf());

View file

@ -84,6 +84,7 @@ import buildcraft.robotics.ai.AIRobotGotoStationToLoad;
import buildcraft.robotics.ai.AIRobotGotoStationToLoadFluids;
import buildcraft.robotics.ai.AIRobotGotoStationToUnload;
import buildcraft.robotics.ai.AIRobotGotoStationToUnloadFluids;
import buildcraft.robotics.ai.AIRobotHarvest;
import buildcraft.robotics.ai.AIRobotLoad;
import buildcraft.robotics.ai.AIRobotLoadFluids;
import buildcraft.robotics.ai.AIRobotMain;
@ -309,6 +310,7 @@ public class BuildCraftRobotics extends BuildCraftMod {
RobotManager.registerAIRobot(AIRobotGotoStationToLoadFluids.class, "aiRobotGotoStationToLoadFluids", "buildcraft.core.robots.AIRobotGotoStationToLoadFluids");
RobotManager.registerAIRobot(AIRobotGotoStationToUnload.class, "aiRobotGotoStationToUnload", "buildcraft.core.robots.AIRobotGotoStationToUnload");
RobotManager.registerAIRobot(AIRobotGotoStationToUnloadFluids.class, "aiRobotGotoStationToUnloadFluids", "buildcraft.core.robots.AIRobotGotoStationToUnloadFluids");
RobotManager.registerAIRobot(AIRobotHarvest.class, "aiRobotHarvest");
RobotManager.registerAIRobot(AIRobotLoad.class, "aiRobotLoad", "buildcraft.core.robots.AIRobotLoad");
RobotManager.registerAIRobot(AIRobotLoadFluids.class, "aiRobotLoadFluids", "buildcraft.core.robots.AIRobotLoadFluids");
RobotManager.registerAIRobot(AIRobotPumpBlock.class, "aiRobotPumpBlock", "buildcraft.core.robots.AIRobotPumpBlock");

View file

@ -0,0 +1,93 @@
package buildcraft.core.crops;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockMelon;
import net.minecraft.block.BlockMushroom;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.crops.ICropHandler;
import buildcraft.core.lib.utils.BlockUtils;
public class CropHandlerPlantable implements ICropHandler {
@Override
public boolean isSeed(ItemStack stack) {
if (stack.getItem() instanceof IPlantable) {
return true;
}
if (stack.getItem() instanceof ItemBlock) {
Block block = ((ItemBlock) stack.getItem()).field_150939_a;
if (block instanceof IPlantable && block != Blocks.reeds) {
return true;
}
}
return false;
}
@Override
public boolean canSustainPlant(World world, ItemStack seed, int x, int y, int z) {
if (seed.getItem() instanceof IPlantable) {
return world.getBlock(x, y, z).canSustainPlant(world, x, y, z, ForgeDirection.UP,
(IPlantable) seed.getItem())
&& world.isAirBlock(x, y + 1, z);
} else {
Block block = world.getBlock(x, y, z);
IPlantable plantable = (IPlantable) ((ItemBlock) seed.getItem()).field_150939_a;
return block.canSustainPlant(world, x, y, z, ForgeDirection.UP, plantable)
&& block != ((ItemBlock) seed.getItem()).field_150939_a
&& world.isAirBlock(x, y + 1, z);
}
}
@Override
public boolean isMature(IBlockAccess blockAccess, Block block, int meta, int x, int y, int z) {
if (block == null) {
return false;
} else if (block instanceof BlockFlower
|| block instanceof BlockTallGrass
|| block instanceof BlockMelon
|| block instanceof BlockMushroom
|| block instanceof BlockDoublePlant
|| block == Blocks.pumpkin) {
return true;
} else if (block instanceof BlockCrops) {
return meta == 7;
} else if (block instanceof IPlantable) {
if (y > 0 && blockAccess.getBlock(x, y - 1, z) == block) {
return true;
}
}
return false;
}
@Override
public boolean harvestCrop(World world, int x, int y, int z, List<ItemStack> drops) {
if (!world.isRemote) {
Block block = world.getBlock(x, y, z);
int meta = world.getBlockMetadata(x, y, z);
if (BlockUtils.breakBlock((WorldServer) world, x, y, z, drops)) {
world.playAuxSFXAtEntity(null, 2001, x, y, z, Block.getIdFromBlock(block)
+ (meta << 12));
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,59 @@
package buildcraft.core.crops;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.crops.ICropHandler;
import buildcraft.core.lib.utils.BlockUtils;
public class CropHandlerReeds implements ICropHandler {
@Override
public boolean isSeed(ItemStack stack) {
return stack.getItem() == Items.reeds;
}
@Override
public boolean canSustainPlant(World world, ItemStack seed, int x, int y, int z) {
Block block = world.getBlock(x, y, z);
return block.canSustainPlant(world, x, y, z, ForgeDirection.UP, (IPlantable) Blocks.reeds)
&& block != Blocks.reeds && world.isAirBlock(x, y + 1, z);
}
@Override
public boolean isMature(IBlockAccess blockAccess, Block block, int meta, int x, int y, int z) {
if (block == null) {
return false;
} else if (block == Blocks.reeds) {
if (y > 0 && blockAccess.getBlock(x, y - 1, z) == block) {
return true;
}
}
return false;
}
@Override
public boolean harvestCrop(World world, int x, int y, int z, List<ItemStack> drops) {
if (!world.isRemote) {
Block block = world.getBlock(x, y, z);
int meta = world.getBlockMetadata(x, y, z);
if (BlockUtils.breakBlock((WorldServer) world, x, y, z, drops)) {
world.playAuxSFXAtEntity(null, 2001, x, y, z, Block.getIdFromBlock(block)
+ (meta << 12));
return true;
}
}
return false;
}
}

View file

@ -76,6 +76,18 @@ public final class BlockUtils {
}
public static boolean breakBlock(WorldServer world, int x, int y, int z, int forcedLifespan) {
List<ItemStack> items = new ArrayList<ItemStack>();
if (breakBlock(world, x, y, z, items)) {
for (ItemStack item : items) {
dropItem(world, x, y, z, forcedLifespan, item);
}
return true;
}
return false;
}
public static boolean breakBlock(WorldServer world, int x, int y, int z, List<ItemStack> drops) {
BreakEvent breakEvent = new BreakEvent(x, y, z, world, world.getBlock(x, y, z),
world.getBlockMetadata(x, y, z), CoreProxy.proxy.getBuildCraftPlayer(world).get());
MinecraftForge.EVENT_BUS.post(breakEvent);
@ -84,14 +96,10 @@ public final class BlockUtils {
return false;
}
if (!world.isAirBlock(x, y, z) && !world.isRemote && world.getGameRules().getGameRuleBooleanValue("doTileDrops")) {
List<ItemStack> items = getItemStackFromBlock(world, x, y, z);
for (ItemStack item : items) {
dropItem(world, x, y, z, forcedLifespan, item);
}
if (!world.isAirBlock(x, y, z) && !world.isRemote
&& world.getGameRules().getGameRuleBooleanValue("doTileDrops")) {
drops.addAll(getItemStackFromBlock(world, x, y, z));
}
world.setBlockToAir(x, y, z);
return true;

View file

@ -9,36 +9,14 @@
package buildcraft.core.properties;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCactus;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockMelon;
import net.minecraft.block.BlockMushroom;
import net.minecraft.block.BlockReed;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.world.IBlockAccess;
import buildcraft.api.crops.CropManager;
public class WorldPropertyIsHarvestable extends WorldProperty {
@Override
public boolean get(IBlockAccess blockAccess, Block block, int meta, int x, int y, int z) {
if (block == null) {
return false;
} else if (block instanceof BlockFlower
|| block instanceof BlockTallGrass
|| block instanceof BlockMelon
|| block instanceof BlockMushroom
|| block instanceof BlockDoublePlant) {
return true;
} else if (block instanceof BlockCactus || block instanceof BlockReed) {
if (y > 0 && blockAccess.getBlock(x, y - 1, z) == block) {
return true;
}
} else if (block instanceof BlockCrops) {
return meta == 7;
}
return false;
return CropManager.isMature(blockAccess, block, meta, x, y, z);
}
}

View file

@ -0,0 +1,81 @@
package buildcraft.robotics.ai;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MathHelper;
import net.minecraft.world.WorldServer;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.crops.CropManager;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.core.lib.utils.BlockUtils;
public class AIRobotHarvest extends AIRobot {
private BlockIndex blockFound;
private int delay = 0;
public AIRobotHarvest(EntityRobotBase iRobot) {
super(iRobot);
}
public AIRobotHarvest(EntityRobotBase iRobot, BlockIndex iBlockFound) {
super(iRobot);
blockFound = iBlockFound;
}
@Override
public void update() {
if (blockFound == null) {
setSuccess(false);
terminate();
return;
}
if (delay++ > 20) {
if (!BuildCraftAPI.getWorldProperty("harvestable").get(robot.worldObj, blockFound.x,
blockFound.y, blockFound.z)) {
setSuccess(false);
terminate();
return;
}
List<ItemStack> drops = new ArrayList<ItemStack>();
if (!CropManager.harvestCrop(robot.worldObj, blockFound.x, blockFound.y, blockFound.z,
drops)) {
setSuccess(false);
terminate();
return;
}
for (ItemStack stack : drops) {
BlockUtils.dropItem((WorldServer) robot.worldObj,
MathHelper.floor_double(robot.posX), MathHelper.floor_double(robot.posY),
MathHelper.floor_double(robot.posZ), 6000, stack);
}
}
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (blockFound != null) {
NBTTagCompound sub = new NBTTagCompound();
blockFound.writeTo(sub);
nbt.setTag("blockFound", sub);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("blockFound")) {
blockFound = new BlockIndex(nbt.getCompoundTag("blockFound"));
}
}
}

View file

@ -8,36 +8,15 @@
*/
package buildcraft.robotics.boards;
import java.util.ArrayList;
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.ResourceIdBlock;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.api.statements.StatementParameterItemStack;
import buildcraft.api.statements.StatementSlot;
import buildcraft.core.lib.inventory.filters.IStackFilter;
import buildcraft.core.lib.utils.IBlockFilter;
import buildcraft.robotics.ai.AIRobotBreak;
import buildcraft.robotics.ai.AIRobotFetchAndEquipItemStack;
import buildcraft.robotics.ai.AIRobotGotoSleep;
import buildcraft.robotics.ai.AIRobotSearchAndGotoBlock;
import buildcraft.robotics.statements.ActionRobotFilter;
public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot {
protected BlockIndex blockFound;
private ArrayList<Block> blockFilter = new ArrayList<Block>();
private ArrayList<Integer> metaFilter = new ArrayList<Integer>();
public abstract class BoardRobotGenericBreakBlock extends BoardRobotGenericSearchBlock {
public BoardRobotGenericBreakBlock(EntityRobotBase iRobot) {
super(iRobot);
@ -45,13 +24,6 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot {
public abstract boolean isExpectedTool(ItemStack stack);
/**
* This function has to be derived in a thread safe manner, as it may be
* called from parallel jobs. In particular, world should not be directly
* used, only through WorldProperty class and subclasses.
*/
public abstract boolean isExpectedBlock(World world, int x, int y, int z);
@Override
public final void update() {
if (!isExpectedTool(null) && robot.getHeldItem() == null) {
@ -61,112 +33,18 @@ public abstract class BoardRobotGenericBreakBlock extends RedstoneBoardRobot {
return isExpectedTool(stack);
}
}));
} else if (blockFound() != null) {
startDelegateAI(new AIRobotBreak(robot, blockFound()));
} else {
updateFilter();
startDelegateAI(new AIRobotSearchAndGotoBlock(robot, false, new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
if (isExpectedBlock(world, x, y, z) && !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))) {
return matchesGateFilter(world, x, y, z);
} else {
return false;
}
}
}));
super.update();
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotSearchAndGotoBlock) {
if (ai.success()) {
blockFound = ((AIRobotSearchAndGotoBlock) ai).getBlockFound();
startDelegateAI(getBlockBreakAI());
} else {
startDelegateAI(new AIRobotGotoSleep(robot));
}
} else if (ai.getClass().isInstance(getBlockBreakAI())) {
// TODO: if !ai.success() -> can't break block, blacklist it
releaseBlockFound();
}
}
protected AIRobot getBlockBreakAI() {
return new AIRobotBreak(robot, blockFound);
}
private void releaseBlockFound() {
if (blockFound != null) {
robot.getRegistry().release(new ResourceIdBlock(blockFound));
blockFound = null;
}
}
@Override
public void end() {
releaseBlockFound();
}
public final void updateFilter() {
blockFilter.clear();
metaFilter.clear();
for (StatementSlot slot : robot.getLinkedStation().getActiveActions()) {
if (slot.statement instanceof ActionRobotFilter) {
for (IStatementParameter p : slot.parameters) {
if (p != null && p instanceof StatementParameterItemStack) {
StatementParameterItemStack param = (StatementParameterItemStack) p;
ItemStack stack = param.getItemStack();
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;
}
Block block;
int meta;
synchronized (world) {
block = world.getBlock(x, y, z);
meta = world.getBlockMetadata(x, y, z);
}
for (int i = 0; i < blockFilter.size(); ++i) {
if (blockFilter.get(i) == block && metaFilter.get(i) == meta) {
return true;
}
}
return false;
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (blockFound != null) {
NBTTagCompound sub = new NBTTagCompound();
blockFound.writeTo(sub);
nbt.setTag("indexStored", sub);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("indexStored")) {
blockFound = new BlockIndex (nbt.getCompoundTag("indexStored"));
if (ai instanceof AIRobotBreak) {
releaseBlockFound(ai.success());
}
super.delegateAIEnded(ai);
}
}

View file

@ -0,0 +1,148 @@
package buildcraft.robotics.boards;
import java.util.ArrayList;
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.ResourceIdBlock;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.api.statements.StatementParameterItemStack;
import buildcraft.api.statements.StatementSlot;
import buildcraft.core.lib.utils.IBlockFilter;
import buildcraft.robotics.ai.AIRobotGotoSleep;
import buildcraft.robotics.ai.AIRobotSearchAndGotoBlock;
import buildcraft.robotics.statements.ActionRobotFilter;
public abstract class BoardRobotGenericSearchBlock extends RedstoneBoardRobot {
private BlockIndex blockFound;
private ArrayList<Block> blockFilter = new ArrayList<Block>();
private ArrayList<Integer> metaFilter = new ArrayList<Integer>();
public BoardRobotGenericSearchBlock(EntityRobotBase iRobot) {
super(iRobot);
}
/**
* This function has to be derived in a thread safe manner, as it may be
* called from parallel jobs. In particular, world should not be directly
* used, only through WorldProperty class and subclasses.
*/
public abstract boolean isExpectedBlock(World world, int x, int y, int z);
@Override
public void update() {
updateFilter();
startDelegateAI(new AIRobotSearchAndGotoBlock(robot, false, new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
if (isExpectedBlock(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 AIRobotSearchAndGotoBlock) {
if (ai.success()) {
blockFound = ((AIRobotSearchAndGotoBlock) ai).getBlockFound();
} else {
startDelegateAI(new AIRobotGotoSleep(robot));
}
}
}
@Override
public void end() {
releaseBlockFound(true);
}
protected BlockIndex blockFound() {
return blockFound;
}
protected void releaseBlockFound(boolean success) {
if (blockFound != null) {
// TODO: if !ai.success() -> can't break block, blacklist it
robot.getRegistry().release(new ResourceIdBlock(blockFound));
blockFound = null;
}
}
public final void updateFilter() {
blockFilter.clear();
metaFilter.clear();
for (StatementSlot slot : robot.getLinkedStation().getActiveActions()) {
if (slot.statement instanceof ActionRobotFilter) {
for (IStatementParameter p : slot.parameters) {
if (p != null && p instanceof StatementParameterItemStack) {
StatementParameterItemStack param = (StatementParameterItemStack) p;
ItemStack stack = param.getItemStack();
if (stack != null && stack.getItem() instanceof ItemBlock) {
blockFilter.add(((ItemBlock) stack.getItem()).field_150939_a);
metaFilter.add(stack.getItemDamage());
}
}
}
}
}
}
protected boolean matchesGateFilter(World world, int x, int y, int z) {
if (blockFilter.size() == 0) {
return true;
}
Block block;
int meta;
synchronized (world) {
block = world.getBlock(x, y, z);
meta = world.getBlockMetadata(x, y, z);
}
for (int i = 0; i < blockFilter.size(); ++i) {
if (blockFilter.get(i) == block && metaFilter.get(i) == meta) {
return true;
}
}
return false;
}
@Override
public void writeSelfToNBT(NBTTagCompound nbt) {
super.writeSelfToNBT(nbt);
if (blockFound != null) {
NBTTagCompound sub = new NBTTagCompound();
blockFound.writeTo(sub);
nbt.setTag("indexStored", sub);
}
}
@Override
public void loadSelfFromNBT(NBTTagCompound nbt) {
super.loadSelfFromNBT(nbt);
if (nbt.hasKey("indexStored")) {
blockFound = new BlockIndex(nbt.getCompoundTag("indexStored"));
}
}
}

View file

@ -8,15 +8,16 @@
*/
package buildcraft.robotics.boards;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.robotics.ai.AIRobotHarvest;
public class BoardRobotHarvester extends BoardRobotGenericBreakBlock {
public class BoardRobotHarvester extends BoardRobotGenericSearchBlock {
public BoardRobotHarvester(EntityRobotBase iRobot) {
super(iRobot);
@ -31,13 +32,25 @@ public class BoardRobotHarvester extends BoardRobotGenericBreakBlock {
return BCBoardNBT.REGISTRY.get("harvester");
}
@Override
public boolean isExpectedTool(ItemStack stack) {
return true;
}
@Override
public boolean isExpectedBlock(World world, int x, int y, int z) {
return BuildCraftAPI.getWorldProperty("harvestable").get(world, x, y, z);
}
@Override
public void update() {
if (blockFound() != null) {
startDelegateAI(new AIRobotHarvest(robot, blockFound()));
} else {
super.update();
}
}
@Override
public void delegateAIEnded(AIRobot ai) {
if (ai instanceof AIRobotHarvest) {
releaseBlockFound(ai.success());
}
super.delegateAIEnded(ai);
}
}

View file

@ -8,29 +8,18 @@
*/
package buildcraft.robotics.boards;
import java.util.ArrayList;
import java.util.Collection;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemReed;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.crops.CropManager;
import buildcraft.api.robots.AIRobot;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.ResourceIdBlock;
import buildcraft.core.lib.inventory.filters.ArrayStackFilter;
import buildcraft.core.lib.inventory.filters.ArrayStackOrListFilter;
import buildcraft.core.lib.inventory.filters.CompositeFilter;
import buildcraft.core.lib.inventory.filters.AggregateFilter;
import buildcraft.core.lib.inventory.filters.IStackFilter;
import buildcraft.core.lib.utils.IBlockFilter;
import buildcraft.robotics.ai.AIRobotFetchAndEquipItemStack;
@ -41,8 +30,14 @@ import buildcraft.robotics.statements.ActionRobotFilter;
public class BoardRobotPlanter extends RedstoneBoardRobot {
private IStackFilter stackFilter = new CompositeFilter(new PlantableFilter(), new ReedFilter());
private BlockIndex blockFound;
private IStackFilter filter = new IStackFilter() {
@Override
public boolean matches(ItemStack stack) {
return CropManager.isSeed(stack);
}
};
public BoardRobotPlanter(EntityRobotBase iRobot) {
super(iRobot);
@ -56,62 +51,17 @@ public class BoardRobotPlanter extends RedstoneBoardRobot {
@Override
public void update() {
if (robot.getHeldItem() == null) {
Collection<ItemStack> gateFilter = ActionRobotFilter.getGateFilterStacks(robot
.getLinkedStation());
if (gateFilter.size() != 0) {
ArrayList<ItemStack> filteredFilter = new ArrayList<ItemStack>();
for (ItemStack tentative : gateFilter) {
if (stackFilter.matches(tentative)) {
filteredFilter.add(tentative);
}
}
if (filteredFilter.size() > 0) {
ArrayStackFilter arrayFilter = new ArrayStackOrListFilter(
filteredFilter.toArray(new ItemStack[filteredFilter.size()]));
startDelegateAI(new AIRobotFetchAndEquipItemStack(robot, arrayFilter));
} else {
startDelegateAI(new AIRobotGotoSleep(robot));
}
} else {
startDelegateAI(new AIRobotFetchAndEquipItemStack(robot, stackFilter));
}
startDelegateAI(new AIRobotFetchAndEquipItemStack(robot, new AggregateFilter(filter,
ActionRobotFilter.getGateFilter(robot.getLinkedStation()))));
} else {
final ItemStack itemStack = robot.getHeldItem();
IBlockFilter blockFilter;
if (itemStack.getItem() instanceof ItemReed) {
blockFilter = new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
return isPlantable((IPlantable) Blocks.reeds, Blocks.reeds, world, x, y, z)
&& !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))
&& isAirAbove(world, x, y, z);
}
};
} else if (itemStack.getItem() instanceof ItemBlock) {
final Block plantBlock = ((ItemBlock) itemStack.getItem()).field_150939_a;
blockFilter = new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
return isPlantable((IPlantable) plantBlock, plantBlock, world, x, y, z)
&& !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))
&& isAirAbove(world, x, y, z);
}
};
} else {
blockFilter = new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
return isPlantable((IPlantable) itemStack.getItem(), null, world, x, y, z)
&& !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z))
&& isAirAbove(world, x, y, z);
}
};
}
IBlockFilter blockFilter = new IBlockFilter() {
@Override
public boolean matches(World world, int x, int y, int z) {
return isPlantable(itemStack, world, x, y, z)
&& !robot.getRegistry().isTaken(new ResourceIdBlock(x, y, z));
}
};
startDelegateAI(new AIRobotSearchAndGotoBlock(robot, true, blockFilter));
}
}
@ -141,36 +91,9 @@ public class BoardRobotPlanter extends RedstoneBoardRobot {
}
}
private static class PlantableFilter implements IStackFilter {
@Override
public boolean matches(ItemStack stack) {
if (stack.getItem() instanceof IPlantable) {
return true;
}
if (stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).field_150939_a instanceof IPlantable) {
return true;
}
return false;
}
}
private static class ReedFilter implements IStackFilter {
@Override
public boolean matches(ItemStack stack) {
return stack.getItem() == Items.reeds;
}
}
private boolean isPlantable(IPlantable plant, Block block, World world, int x, int y, int z) {
private boolean isPlantable(ItemStack seed, World world, int x, int y, int z) {
synchronized (world) {
return world.getBlock(x, y, z).canSustainPlant(world, x, y, z, ForgeDirection.UP, plant)
&& (block == null || world.getBlock(x, y, z) != block);
}
}
private boolean isAirAbove(World world, int x, int y, int z) {
synchronized (world) {
return world.isAirBlock(x, y + 1, z);
return CropManager.canSustainPlant(world, seed, x, y, z);
}
}