add crop api
This commit is contained in:
parent
633629792e
commit
c3e0eeb3d0
13 changed files with 573 additions and 265 deletions
57
api/buildcraft/api/crops/CropManager.java
Normal file
57
api/buildcraft/api/crops/CropManager.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
59
api/buildcraft/api/crops/ICropHandler.java
Normal file
59
api/buildcraft/api/crops/ICropHandler.java
Normal 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);
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
|
|
93
common/buildcraft/core/crops/CropHandlerPlantable.java
Normal file
93
common/buildcraft/core/crops/CropHandlerPlantable.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
59
common/buildcraft/core/crops/CropHandlerReeds.java
Normal file
59
common/buildcraft/core/crops/CropHandlerReeds.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
81
common/buildcraft/robotics/ai/AIRobotHarvest.java
Normal file
81
common/buildcraft/robotics/ai/AIRobotHarvest.java
Normal 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"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue