Added the ability to add custom farmer behaviors to the API

This commit is contained in:
Ellpeck 2016-12-04 15:03:01 +01:00
parent 6d194879bf
commit 9552c112b0
16 changed files with 374 additions and 168 deletions

View file

@ -13,6 +13,7 @@ package de.ellpeck.actuallyadditions.api;
import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter;
import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry;
import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletPage;
import de.ellpeck.actuallyadditions.api.farmer.IFarmerBehavior;
import de.ellpeck.actuallyadditions.api.internal.IMethodHandler; import de.ellpeck.actuallyadditions.api.internal.IMethodHandler;
import de.ellpeck.actuallyadditions.api.laser.ILaserRelayConnectionHandler; import de.ellpeck.actuallyadditions.api.laser.ILaserRelayConnectionHandler;
import de.ellpeck.actuallyadditions.api.lens.Lens; import de.ellpeck.actuallyadditions.api.lens.Lens;
@ -31,7 +32,7 @@ public final class ActuallyAdditionsAPI{
public static final String MOD_ID = "actuallyadditions"; public static final String MOD_ID = "actuallyadditions";
public static final String API_ID = MOD_ID+"api"; public static final String API_ID = MOD_ID+"api";
public static final String API_VERSION = "31"; public static final String API_VERSION = "32";
public static final List<CrusherRecipe> CRUSHER_RECIPES = new ArrayList<CrusherRecipe>(); public static final List<CrusherRecipe> CRUSHER_RECIPES = new ArrayList<CrusherRecipe>();
public static final List<BallOfFurReturn> BALL_OF_FUR_RETURN_ITEMS = new ArrayList<BallOfFurReturn>(); public static final List<BallOfFurReturn> BALL_OF_FUR_RETURN_ITEMS = new ArrayList<BallOfFurReturn>();
@ -39,6 +40,7 @@ public final class ActuallyAdditionsAPI{
public static final List<LensConversionRecipe> RECONSTRUCTOR_LENS_CONVERSION_RECIPES = new ArrayList<LensConversionRecipe>(); public static final List<LensConversionRecipe> RECONSTRUCTOR_LENS_CONVERSION_RECIPES = new ArrayList<LensConversionRecipe>();
public static final List<EmpowererRecipe> EMPOWERER_RECIPES = new ArrayList<EmpowererRecipe>(); public static final List<EmpowererRecipe> EMPOWERER_RECIPES = new ArrayList<EmpowererRecipe>();
public static final Map<Item, IColorLensChanger> RECONSTRUCTOR_LENS_COLOR_CHANGERS = new HashMap<Item, IColorLensChanger>(); public static final Map<Item, IColorLensChanger> RECONSTRUCTOR_LENS_COLOR_CHANGERS = new HashMap<Item, IColorLensChanger>();
public static final List<IFarmerBehavior> FARMER_BEHAVIORS = new ArrayList<IFarmerBehavior>();
public static final List<CoffeeIngredient> COFFEE_MACHINE_INGREDIENTS = new ArrayList<CoffeeIngredient>(); public static final List<CoffeeIngredient> COFFEE_MACHINE_INGREDIENTS = new ArrayList<CoffeeIngredient>();
public static final List<CompostRecipe> COMPOST_RECIPES = new ArrayList<CompostRecipe>(); public static final List<CompostRecipe> COMPOST_RECIPES = new ArrayList<CompostRecipe>();
public static final List<OilGenRecipe> OIL_GENERATOR_RECIPES = new ArrayList<OilGenRecipe>(); public static final List<OilGenRecipe> OIL_GENERATOR_RECIPES = new ArrayList<OilGenRecipe>();
@ -247,4 +249,13 @@ public final class ActuallyAdditionsAPI{
public static void addBookletEntry(IBookletEntry entry){ public static void addBookletEntry(IBookletEntry entry){
BOOKLET_ENTRIES.add(entry); BOOKLET_ENTRIES.add(entry);
} }
/**
* Adds a new farmer behavior to the Farmer
*
* @param behavior The behavior to add
*/
public static void addFarmerBehavior(IFarmerBehavior behavior){
FARMER_BEHAVIORS.add(behavior);
}
} }

View file

@ -0,0 +1,43 @@
/*
* This file ("IFarmBehavior.java") is part of the Actually Additions mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://ellpeck.de/actaddlicense
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015-2016 Ellpeck
*/
package de.ellpeck.actuallyadditions.api.farmer;
import de.ellpeck.actuallyadditions.api.internal.IFarmer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IFarmerBehavior{
/**
* Try to plant a seed with this behavior
* If this method return true, the seed ItemStack will have one item deducted from it.
*
* @param seed The seed stack to plant
* @param world The world
* @param pos The position to plant the seed on
* @param farmer The Farmer doing this action. Can be used to query and extract energy and add items to the slots
* @return If planting was successful
*/
boolean tryPlantSeed(ItemStack seed, World world, BlockPos pos, IFarmer farmer);
/**
* Try to harvest a plant with this behavior
*
* @param world The world
* @param pos The position of the plant
* @param farmer The Farmer doing this action. Can be used to query and extract energy and add items to the slots
* @return If harvesting was successful
*/
boolean tryHarvestPlant(World world, BlockPos pos, IFarmer farmer);
}

View file

@ -12,45 +12,14 @@ package de.ellpeck.actuallyadditions.api.internal;
import de.ellpeck.actuallyadditions.api.lens.Lens; import de.ellpeck.actuallyadditions.api.lens.Lens;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
/** /**
* This is a helper interface for Lens' invoke() method. * This is a helper interface for Lens' invoke() method.
* This is not supposed to be implemented.
* <p> * <p>
* This is not supposed to be implemented.
* Can be cast to TileEntity. * Can be cast to TileEntity.
*/ */
public interface IAtomicReconstructor{ public interface IAtomicReconstructor extends IEnergyTile{
/**
* Returns the x coord of the reconstructor
*/
int getX();
/**
* Returns the y coord of the reconstructor
*/
int getY();
/**
* Returns the z coord of the reconstructor
*/
int getZ();
/**
* Returns the world of the reconstructor
*/
World getWorldObject();
/**
* Extracts a specified amount of energy from the Reconstructor's RF storage
*/
void extractEnergy(int amount);
/**
* Gets the amount of energy the Reconstructor has stored in its RF storage
*/
int getEnergy();
Lens getLens(); Lens getLens();

View file

@ -0,0 +1,32 @@
/*
* This file ("IEnergyTile.java") is part of the Actually Additions mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://ellpeck.de/actaddlicense
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015-2016 Ellpeck
*/
package de.ellpeck.actuallyadditions.api.internal;
import net.minecraft.world.World;
/**
* This is not supposed to be implemented.
* Can be cast to TileEntity.
*/
public interface IEnergyTile{
int getX();
int getY();
int getZ();
World getWorldObject();
void extractEnergy(int amount);
int getEnergy();
}

View file

@ -0,0 +1,31 @@
/*
* This file ("IFarmer.java") is part of the Actually Additions mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://ellpeck.de/actaddlicense
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015-2016 Ellpeck
*/
package de.ellpeck.actuallyadditions.api.internal;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import java.util.List;
/**
* This is a helper interface for IFarmerBehavior.
* <p>
* This is not supposed to be implemented.
* Can be cast to TileEntity.
*/
public interface IFarmer extends IEnergyTile{
EnumFacing getOrientation();
boolean addToSeedInventory(List<ItemStack> stacks, boolean actuallyDo);
boolean addToOutputInventory(List<ItemStack> stacks, boolean actuallyDo);
}

View file

@ -32,9 +32,10 @@ import de.ellpeck.actuallyadditions.mod.items.lens.Lenses;
import de.ellpeck.actuallyadditions.mod.material.InitArmorMaterials; import de.ellpeck.actuallyadditions.mod.material.InitArmorMaterials;
import de.ellpeck.actuallyadditions.mod.material.InitToolMaterials; import de.ellpeck.actuallyadditions.mod.material.InitToolMaterials;
import de.ellpeck.actuallyadditions.mod.misc.BannerHelper; import de.ellpeck.actuallyadditions.mod.misc.BannerHelper;
import de.ellpeck.actuallyadditions.mod.misc.LaserRelayConnectionHandler; import de.ellpeck.actuallyadditions.mod.misc.apiimpl.LaserRelayConnectionHandler;
import de.ellpeck.actuallyadditions.mod.misc.MethodHandler; import de.ellpeck.actuallyadditions.mod.misc.apiimpl.MethodHandler;
import de.ellpeck.actuallyadditions.mod.misc.SoundHandler; import de.ellpeck.actuallyadditions.mod.misc.SoundHandler;
import de.ellpeck.actuallyadditions.mod.misc.apiimpl.farmer.DefaultFarmerBehavior;
import de.ellpeck.actuallyadditions.mod.network.PacketHandler; import de.ellpeck.actuallyadditions.mod.network.PacketHandler;
import de.ellpeck.actuallyadditions.mod.ore.InitOreDict; import de.ellpeck.actuallyadditions.mod.ore.InitOreDict;
import de.ellpeck.actuallyadditions.mod.proxy.IProxy; import de.ellpeck.actuallyadditions.mod.proxy.IProxy;

View file

@ -209,7 +209,7 @@ public final class InitBooklet{
new BookletChapter("rangedCollector", ActuallyAdditionsAPI.entryFunctionalNonRF, new ItemStack(InitBlocks.blockRangedCollector), new PageTextOnly(1).addTextReplacement("<range>", TileEntityRangedCollector.RANGE), new PageCrafting(2, BlockCrafting.recipeRangedCollector).setNoText()); new BookletChapter("rangedCollector", ActuallyAdditionsAPI.entryFunctionalNonRF, new ItemStack(InitBlocks.blockRangedCollector), new PageTextOnly(1).addTextReplacement("<range>", TileEntityRangedCollector.RANGE), new PageCrafting(2, BlockCrafting.recipeRangedCollector).setNoText());
//RF Using Blocks //RF Using Blocks
new BookletChapter("farmer", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockFarmer), new PageTextOnly(1).addTextReplacement("<energy>", TileEntityFarmer.USE_PER_OPERATION), new PageCrafting(2, BlockCrafting.recipeFarmer).setWildcard().setNoText()).setImportant(); new BookletChapter("farmer", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockFarmer), new PageTextOnly(1), new PageCrafting(2, BlockCrafting.recipeFarmer).setWildcard().setNoText()).setImportant();
new BookletChapter("fireworkBox", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockFireworkBox), new PageTextOnly(1).addTextReplacement("<rf>", TileEntityFireworkBox.USE_PER_SHOT), new PageCrafting(2, BlockCrafting.recipeFireworkBox)).setSpecial(); new BookletChapter("fireworkBox", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockFireworkBox), new PageTextOnly(1).addTextReplacement("<rf>", TileEntityFireworkBox.USE_PER_SHOT), new PageCrafting(2, BlockCrafting.recipeFireworkBox)).setSpecial();
new BookletChapter("miner", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockMiner), new PageTextOnly(1).addTextReplacement("<rf>", TileEntityMiner.ENERGY_USE_PER_BLOCK).addTextReplacement("<range>", TileEntityMiner.DEFAULT_RANGE), new PageCrafting(2, BlockCrafting.recipeMiner)).setSpecial(); new BookletChapter("miner", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockMiner), new PageTextOnly(1).addTextReplacement("<rf>", TileEntityMiner.ENERGY_USE_PER_BLOCK).addTextReplacement("<range>", TileEntityMiner.DEFAULT_RANGE), new PageCrafting(2, BlockCrafting.recipeMiner)).setSpecial();
new BookletChapterCoffee("coffeeMachine", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockCoffeeMachine), new PageTextOnly(1).addItemToPage(new ItemStack(InitItems.itemCoffeeBean)).addTextReplacement("<rf>", TileEntityCoffeeMachine.ENERGY_USED).addTextReplacement("<coffee>", TileEntityCoffeeMachine.CACHE_USE).addTextReplacement("<water>", TileEntityCoffeeMachine.WATER_USE), new PageTextOnly(2).addItemToPage(new ItemStack(InitItems.itemCoffee)), new PagePicture(3, "page_coffee_machine", 115), new PageCrafting(4, BlockCrafting.recipeCoffeeMachine).setWildcard().setNoText(), new PageCrafting(5, ItemCrafting.recipeCup).setNoText()).setImportant(); new BookletChapterCoffee("coffeeMachine", ActuallyAdditionsAPI.entryFunctionalRF, new ItemStack(InitBlocks.blockCoffeeMachine), new PageTextOnly(1).addItemToPage(new ItemStack(InitItems.itemCoffeeBean)).addTextReplacement("<rf>", TileEntityCoffeeMachine.ENERGY_USED).addTextReplacement("<coffee>", TileEntityCoffeeMachine.CACHE_USE).addTextReplacement("<water>", TileEntityCoffeeMachine.WATER_USE), new PageTextOnly(2).addItemToPage(new ItemStack(InitItems.itemCoffee)), new PagePicture(3, "page_coffee_machine", 115), new PageCrafting(4, BlockCrafting.recipeCoffeeMachine).setWildcard().setNoText(), new PageCrafting(5, ItemCrafting.recipeCup).setNoText()).setImportant();

View file

@ -14,6 +14,7 @@ import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids;
import de.ellpeck.actuallyadditions.mod.items.InitItems; import de.ellpeck.actuallyadditions.mod.items.InitItems;
import de.ellpeck.actuallyadditions.mod.items.metalists.TheMiscItems; import de.ellpeck.actuallyadditions.mod.items.metalists.TheMiscItems;
import de.ellpeck.actuallyadditions.mod.misc.apiimpl.farmer.DefaultFarmerBehavior;
import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.ModUtil;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -39,6 +40,8 @@ public final class InitCrafting{
ActuallyAdditionsAPI.addOilGenRecipe(InitFluids.fluidCrystalOil.getName(), 80, 350); ActuallyAdditionsAPI.addOilGenRecipe(InitFluids.fluidCrystalOil.getName(), 80, 350);
ActuallyAdditionsAPI.addOilGenRecipe(InitFluids.fluidEmpoweredOil.getName(), 80, 600); ActuallyAdditionsAPI.addOilGenRecipe(InitFluids.fluidEmpoweredOil.getName(), 80, 600);
ActuallyAdditionsAPI.addFarmerBehavior(new DefaultFarmerBehavior());
RecipeSorter.register(ModUtil.MOD_ID+":recipeKeepDataShaped", RecipeKeepDataShaped.class, RecipeSorter.Category.SHAPED, "after:minecraft:shaped"); RecipeSorter.register(ModUtil.MOD_ID+":recipeKeepDataShaped", RecipeKeepDataShaped.class, RecipeSorter.Category.SHAPED, "after:minecraft:shaped");
RecipeSorter.register(ModUtil.MOD_ID+":recipeKeepDataShapeless", RecipeKeepDataShapeless.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless"); RecipeSorter.register(ModUtil.MOD_ID+":recipeKeepDataShapeless", RecipeKeepDataShapeless.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless");

View file

@ -12,7 +12,7 @@ package de.ellpeck.actuallyadditions.mod.data;
import de.ellpeck.actuallyadditions.api.laser.Network; import de.ellpeck.actuallyadditions.api.laser.Network;
import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave; import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave;
import de.ellpeck.actuallyadditions.mod.misc.LaserRelayConnectionHandler; import de.ellpeck.actuallyadditions.mod.misc.apiimpl.LaserRelayConnectionHandler;
import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.ModUtil;
import io.netty.util.internal.ConcurrentSet; import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;

View file

@ -10,6 +10,7 @@
package de.ellpeck.actuallyadditions.mod.inventory; package de.ellpeck.actuallyadditions.mod.inventory;
import de.ellpeck.actuallyadditions.mod.inventory.slot.SlotItemHandlerUnconditioned;
import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase;
import de.ellpeck.actuallyadditions.mod.tile.TileEntityFarmer; import de.ellpeck.actuallyadditions.mod.tile.TileEntityFarmer;
import de.ellpeck.actuallyadditions.mod.util.StackUtil; import de.ellpeck.actuallyadditions.mod.util.StackUtil;
@ -18,7 +19,6 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container; import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot; import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import de.ellpeck.actuallyadditions.mod.inventory.slot.SlotItemHandlerUnconditioned;
public class ContainerFarmer extends Container{ public class ContainerFarmer extends Container{
@ -65,21 +65,17 @@ public class ContainerFarmer extends Container{
//Other Slots in Inventory excluded //Other Slots in Inventory excluded
if(slot >= inventoryStart){ if(slot >= inventoryStart){
//Shift from Inventory //Shift from Inventory
if(TileEntityFarmer.getPlantableFromStack(newStack) != null){ if(!this.mergeItemStack(newStack, 0, 6, false)){
if(!this.mergeItemStack(newStack, 0, 6, false)){ //
if(slot >= inventoryStart && slot <= inventoryEnd){
if(!this.mergeItemStack(newStack, hotbarStart, hotbarEnd+1, false)){
return StackUtil.getNull();
}
}
else if(slot >= inventoryEnd+1 && slot < hotbarEnd+1 && !this.mergeItemStack(newStack, inventoryStart, inventoryEnd+1, false)){
return StackUtil.getNull(); return StackUtil.getNull();
} }
} }
//
else if(slot >= inventoryStart && slot <= inventoryEnd){
if(!this.mergeItemStack(newStack, hotbarStart, hotbarEnd+1, false)){
return StackUtil.getNull();
}
}
else if(slot >= inventoryEnd+1 && slot < hotbarEnd+1 && !this.mergeItemStack(newStack, inventoryStart, inventoryEnd+1, false)){
return StackUtil.getNull();
}
} }
else if(!this.mergeItemStack(newStack, inventoryStart, hotbarEnd+1, false)){ else if(!this.mergeItemStack(newStack, inventoryStart, hotbarEnd+1, false)){
return StackUtil.getNull(); return StackUtil.getNull();

View file

@ -8,7 +8,7 @@
* © 2015-2016 Ellpeck * © 2015-2016 Ellpeck
*/ */
package de.ellpeck.actuallyadditions.mod.misc; package de.ellpeck.actuallyadditions.mod.misc.apiimpl;
import de.ellpeck.actuallyadditions.api.laser.IConnectionPair; import de.ellpeck.actuallyadditions.api.laser.IConnectionPair;
import de.ellpeck.actuallyadditions.api.laser.LaserType; import de.ellpeck.actuallyadditions.api.laser.LaserType;

View file

@ -8,7 +8,7 @@
* © 2015-2016 Ellpeck * © 2015-2016 Ellpeck
*/ */
package de.ellpeck.actuallyadditions.mod.misc; package de.ellpeck.actuallyadditions.mod.misc.apiimpl;
import de.ellpeck.actuallyadditions.api.laser.IConnectionPair; import de.ellpeck.actuallyadditions.api.laser.IConnectionPair;
import de.ellpeck.actuallyadditions.api.laser.ILaserRelayConnectionHandler; import de.ellpeck.actuallyadditions.api.laser.ILaserRelayConnectionHandler;

View file

@ -8,7 +8,7 @@
* © 2015-2016 Ellpeck * © 2015-2016 Ellpeck
*/ */
package de.ellpeck.actuallyadditions.mod.misc; package de.ellpeck.actuallyadditions.mod.misc.apiimpl;
import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter;

View file

@ -0,0 +1,155 @@
/*
* This file ("DefaultFarmerBehavior.java") is part of the Actually Additions mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://ellpeck.de/actaddlicense
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015-2016 Ellpeck
*/
package de.ellpeck.actuallyadditions.mod.misc.apiimpl.farmer;
import de.ellpeck.actuallyadditions.api.farmer.IFarmerBehavior;
import de.ellpeck.actuallyadditions.api.internal.IFarmer;
import de.ellpeck.actuallyadditions.mod.util.StackUtil;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import java.util.ArrayList;
import java.util.List;
public class DefaultFarmerBehavior implements IFarmerBehavior{
@Override
public boolean tryPlantSeed(ItemStack seed, World world, BlockPos pos, IFarmer farmer){
int use = 350;
if(farmer.getEnergy() >= use*2){
IBlockState state = world.getBlockState(pos);
Block block = state.getBlock();
if(world.isAirBlock(pos) || block.isReplaceable(world, pos)){
BlockPos farmland = pos.down();
Block farmlandBlock = world.getBlockState(farmland).getBlock();
IBlockState toPlant = this.getPlantablePlantFromStack(seed, world, pos);
if(toPlant != null){
if(this.tryPlant(toPlant, world, pos)){
farmer.extractEnergy(use);
return true;
}
else{
if(farmlandBlock instanceof BlockDirt || farmlandBlock instanceof BlockGrass){
world.setBlockState(farmland, Blocks.FARMLAND.getDefaultState(), 2);
world.setBlockToAir(pos);
world.playSound(null, farmland, SoundEvents.ITEM_HOE_TILL, SoundCategory.BLOCKS, 1.0F, 1.0F);
farmer.extractEnergy(use);
if(this.tryPlant(toPlant, world, pos)){
farmer.extractEnergy(use);
return true;
}
}
}
}
}
}
return false;
}
private boolean tryPlant(IBlockState toPlant, World world, BlockPos pos){
BlockCrops plantBlock = (BlockCrops)toPlant.getBlock();
if(plantBlock.canPlaceBlockAt(world, pos) && plantBlock.canBlockStay(world, pos, toPlant)){
//This fixes a bug with Beetroot being able to be planted anywhere because Minecraft sucks
if(plantBlock != Blocks.BEETROOTS || Blocks.WHEAT.canPlaceBlockAt(world, pos)){
world.setBlockState(pos, toPlant, 3);
return true;
}
}
return false;
}
@Override
public boolean tryHarvestPlant(World world, BlockPos pos, IFarmer farmer){
int use = 250;
if(farmer.getEnergy() >= use){
IBlockState state = world.getBlockState(pos);
Block block = state.getBlock();
if(block instanceof BlockCrops){
if(((BlockCrops)block).isMaxAge(state)){
List<ItemStack> seeds = new ArrayList<ItemStack>();
List<ItemStack> other = new ArrayList<ItemStack>();
List<ItemStack> drops = block.getDrops(world, pos, state, 0);
for(ItemStack stack : drops){
if(this.getPlantableFromStack(stack) != null){
seeds.add(stack);
}
else{
other.add(stack);
}
}
boolean putSeeds = true;
if(!farmer.addToSeedInventory(seeds, false)){
other.addAll(seeds);
putSeeds = false;
}
if(farmer.addToOutputInventory(other, false)){
farmer.addToOutputInventory(other, true);
if(putSeeds){
farmer.addToSeedInventory(seeds, true);
}
world.playEvent(2001, pos, Block.getStateId(state));
world.setBlockToAir(pos);
farmer.extractEnergy(use);
return true;
}
}
}
}
return false;
}
private IBlockState getPlantablePlantFromStack(ItemStack stack, World world, BlockPos pos){
if(StackUtil.isValid(stack)){
IPlantable plantable = this.getPlantableFromStack(stack);
if(plantable != null){
IBlockState state = plantable.getPlant(world, pos);
if(state != null && state.getBlock() instanceof BlockCrops){
return state;
}
}
}
return null;
}
private IPlantable getPlantableFromStack(ItemStack stack){
Item item = stack.getItem();
if(item instanceof IPlantable){
return (IPlantable)item;
}
else if(item instanceof ItemBlock){
Block block = Block.getBlockFromItem(item);
if(block instanceof IPlantable){
return (IPlantable)block;
}
}
return null;
}
}

View file

@ -10,31 +10,23 @@
package de.ellpeck.actuallyadditions.mod.tile; package de.ellpeck.actuallyadditions.mod.tile;
import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.api.farmer.IFarmerBehavior;
import de.ellpeck.actuallyadditions.api.internal.IFarmer;
import de.ellpeck.actuallyadditions.mod.util.StackUtil; import de.ellpeck.actuallyadditions.mod.util.StackUtil;
import de.ellpeck.actuallyadditions.mod.util.WorldUtil; import de.ellpeck.actuallyadditions.mod.util.WorldUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.BlockGrass;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.IPlantable; import net.minecraft.world.World;
import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.energy.IEnergyStorage;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TileEntityFarmer extends TileEntityInventoryBase{ public class TileEntityFarmer extends TileEntityInventoryBase implements IFarmer{
public static final int USE_PER_OPERATION = 1500;
public final CustomEnergyStorage storage = new CustomEnergyStorage(100000, 1000, 0); public final CustomEnergyStorage storage = new CustomEnergyStorage(100000, 1000, 0);
private int waitTime; private int waitTime;
@ -47,20 +39,6 @@ public class TileEntityFarmer extends TileEntityInventoryBase{
super(12, "farmer"); super(12, "farmer");
} }
public static IPlantable getPlantableFromStack(ItemStack stack){
Item item = stack.getItem();
if(item instanceof IPlantable){
return (IPlantable)item;
}
else if(item instanceof ItemBlock){
Block block = Block.getBlockFromItem(item);
if(block instanceof IPlantable){
return (IPlantable)block;
}
}
return null;
}
@Override @Override
public void writeSyncableNBT(NBTTagCompound compound, NBTType type){ public void writeSyncableNBT(NBTTagCompound compound, NBTType type){
super.writeSyncableNBT(compound, type); super.writeSyncableNBT(compound, type);
@ -87,87 +65,26 @@ public class TileEntityFarmer extends TileEntityInventoryBase{
public void updateEntity(){ public void updateEntity(){
super.updateEntity(); super.updateEntity();
if(!this.world.isRemote){ if(!this.world.isRemote){
if(!this.isRedstonePowered){ if(!this.isRedstonePowered && this.storage.getEnergyStored() > 0){
if(this.waitTime > 0){ if(this.waitTime > 0){
this.waitTime--; this.waitTime--;
if(this.waitTime <= 0){ if(this.waitTime <= 0){
if(this.storage.getEnergyStored() >= USE_PER_OPERATION){ int radiusAroundCenter = 4;
boolean didSomething = false;
int radiusAroundCenter = 4; IBlockState state = this.world.getBlockState(this.pos);
int meta = state.getBlock().getMetaFromState(state);
BlockPos center = this.pos.offset(EnumFacing.getHorizontal(meta), radiusAroundCenter+1);
IBlockState state = this.world.getBlockState(this.pos); BlockPos query = center.add(this.checkX, 0, this.checkY);
int meta = state.getBlock().getMetaFromState(state); this.checkBehaviors(query);
BlockPos center = this.pos.offset(EnumFacing.getHorizontal(meta), radiusAroundCenter+1);
BlockPos plant = center.add(this.checkX, 0, this.checkY); this.checkX++;
IBlockState plantState = this.world.getBlockState(plant); if(this.checkX > radiusAroundCenter){
Block plantBlock = plantState.getBlock(); this.checkX = -radiusAroundCenter;
this.checkY++;
if(plantBlock instanceof BlockCrops){ if(this.checkY > radiusAroundCenter){
if(((BlockCrops)plantBlock).isMaxAge(plantState)){ this.checkY = -radiusAroundCenter;
List<ItemStack> seeds = new ArrayList<ItemStack>();
List<ItemStack> other = new ArrayList<ItemStack>();
List<ItemStack> drops = plantBlock.getDrops(this.world, plant, plantState, 0);
for(ItemStack stack : drops){
if(getPlantableFromStack(stack) != null){
seeds.add(stack);
}
else{
other.add(stack);
}
}
boolean putSeeds = true;
if(!WorldUtil.addToInventory(this.slots, 0, 6, seeds, false)){
other.addAll(seeds);
putSeeds = false;
}
if(WorldUtil.addToInventory(this.slots, 6, 12, other, false)){
WorldUtil.addToInventory(this.slots, 6, 12, other, true);
if(putSeeds){
WorldUtil.addToInventory(this.slots, 0, 6, seeds, true);
}
this.world.playEvent(2001, plant, Block.getStateId(plantState));
this.world.setBlockToAir(plant);
didSomething = true;
}
}
}
else if(plantBlock.isReplaceable(this.world, plant)){
BlockPos farmland = plant.down();
IBlockState farmlandState = this.world.getBlockState(farmland);
Block farmlandBlock = farmlandState.getBlock();
IBlockState toPlant = this.getFirstPlantablePlantFromSlots(plant);
if(toPlant != null){
this.world.setBlockState(plant, toPlant, 3);
didSomething = true;
}
else if(farmlandBlock instanceof BlockDirt || farmlandBlock instanceof BlockGrass){
this.world.setBlockState(farmland, Blocks.FARMLAND.getDefaultState(), 2);
this.world.setBlockToAir(plant);
this.world.playSound(null, farmland, SoundEvents.ITEM_HOE_TILL, SoundCategory.BLOCKS, 1.0F, 1.0F);
didSomething = true;
}
}
if(didSomething){
this.storage.extractEnergyInternal(USE_PER_OPERATION, false);
}
this.checkX++;
if(this.checkX > radiusAroundCenter){
this.checkX = -radiusAroundCenter;
this.checkY++;
if(this.checkY > radiusAroundCenter){
this.checkY = -radiusAroundCenter;
}
} }
} }
} }
@ -183,26 +100,28 @@ public class TileEntityFarmer extends TileEntityInventoryBase{
} }
} }
private IBlockState getFirstPlantablePlantFromSlots(BlockPos pos){ private void checkBehaviors(BlockPos query){
for(int i = 0; i < 6; i++){ for(IFarmerBehavior behavior : ActuallyAdditionsAPI.FARMER_BEHAVIORS){
ItemStack stack = this.slots.getStackInSlot(i); if(behavior.tryHarvestPlant(this.world, query, this)){
if(StackUtil.isValid(stack)){ return;
IPlantable plantable = getPlantableFromStack(stack); }
if(plantable != null){ else{
IBlockState state = plantable.getPlant(this.world, pos); for(int i = 0; i < this.slots.getSlots(); i++){
if(state != null && state.getBlock() instanceof BlockCrops && state.getBlock().canPlaceBlockAt(this.world, pos)){ ItemStack stack = this.slots.getStackInSlot(i);
this.slots.decrStackSize(i, 1); if(StackUtil.isValid(stack)){
return state; if(behavior.tryPlantSeed(stack, this.world, query, this)){
this.slots.decrStackSize(i, 1);
return;
}
} }
} }
} }
} }
return null;
} }
@Override @Override
public boolean isItemValidForSlot(int i, ItemStack stack){ public boolean isItemValidForSlot(int i, ItemStack stack){
return i < 6 && StackUtil.isValid(stack) && getPlantableFromStack(stack) != null; return i < 6;
} }
@Override @Override
@ -214,4 +133,50 @@ public class TileEntityFarmer extends TileEntityInventoryBase{
public IEnergyStorage getEnergyStorage(EnumFacing facing){ public IEnergyStorage getEnergyStorage(EnumFacing facing){
return this.storage; return this.storage;
} }
@Override
public EnumFacing getOrientation(){
IBlockState state = this.world.getBlockState(this.pos);
return WorldUtil.getDirectionByPistonRotation(state.getBlock().getMetaFromState(state));
}
@Override
public boolean addToSeedInventory(List<ItemStack> stacks, boolean actuallyDo){
return WorldUtil.addToInventory(this.slots, 0, 6, stacks, actuallyDo);
}
@Override
public boolean addToOutputInventory(List<ItemStack> stacks, boolean actuallyDo){
return WorldUtil.addToInventory(this.slots, 6, 12, stacks, actuallyDo);
}
@Override
public int getX(){
return this.pos.getX();
}
@Override
public int getY(){
return this.pos.getY();
}
@Override
public int getZ(){
return this.pos.getZ();
}
@Override
public World getWorldObject(){
return this.world;
}
@Override
public void extractEnergy(int amount){
this.storage.extractEnergyInternal(amount, false);
}
@Override
public int getEnergy(){
return this.storage.getEnergyStored();
}
} }

View file

@ -13,7 +13,7 @@ package de.ellpeck.actuallyadditions.mod.tile;
import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.api.laser.IConnectionPair; import de.ellpeck.actuallyadditions.api.laser.IConnectionPair;
import de.ellpeck.actuallyadditions.api.laser.LaserType; import de.ellpeck.actuallyadditions.api.laser.LaserType;
import de.ellpeck.actuallyadditions.mod.misc.ConnectionPair; import de.ellpeck.actuallyadditions.mod.misc.apiimpl.ConnectionPair;
import io.netty.util.internal.ConcurrentSet; import io.netty.util.internal.ConcurrentSet;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;