package ic2.api.crops;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
/**
* Base agriculture crop.
*
* Any crop extending this can be registered using registerCrop to be added into the game.
*/
public abstract class CropCard {
public CropCard() {
}
/**
* Plant name for identifying this crop within your mod.
*
* The name has to be unique within the mod and is used for saving.
* By default this name will be also used to determine displayKey() and registerSprites().
*
* @note changing name or owner will cause existing crops in users' worlds to disappear.
*
* @return Plant name
*/
public abstract String getName();
/**
* Determine the mod id owning this crop.
*
* The owner serves as a name space. With every mod using a different owner, a mod only has to
* make sure it doesn't have conflicts with name() in itself.
* It's recommended to hard code this to your mod id as specified in the @Mod annotation.
* Do not use IC2's mod id here.
*
* @note changing name or owner will cause existing crops in users' worlds to disappear.
*/
public abstract String getOwner();
/**
* Translation key for display to the player.
*
* It's highly recommended to specify a valid key from your language file here, e.g. add
* "yourmod.crop.yourCropName = Your crop's name" to the language file, override name() to
* return "yourCropName" and override displayName() to return "yourmod.crop."+name().
*
* @return Unlocalized name.
*/
public String getDisplayName() {
return getName(); // return the raw name for backwards compatibility
}
/**
* Your name here, will be shown in "Discovered by:" when analyzing seeds.
*
* @return Your name
*/
public String getDiscoveredBy() {
return "unknown";
}
/**
* Description of your plant. Keep it short, a few characters per line for up to two lines.
* Default is showing attributes of your plant, 2 per line.
*
* @param i line to get, starting from 0
* @return The line
*/
public String desc(int i) {
String[] att = getAttributes();
if (att == null || att.length == 0) return "";
if (i == 0) {
String s = att[0];
if (att.length >= 2) {
s+=", "+att[1];
if (att.length >= 3) s+=",";
}
return s;
}
if (att.length < 3) return "";
String s = att[2];
if (att.length >= 4) s+=", "+att[3];
return s;
}
/**
* Crop roots length. Maximum roots length should be 5.
* @param cropTile reference to ICropTile
* @return roots length use in isBlockBelow
*/
public int getRootsLength(ICropTile cropTile) {
return 1;
}
/**
* Object containing the crop properties info - See ic2.api.crops.CropProperties for more info.
*/
public abstract CropProperties getProperties();
/**
* Additional attributes of the plant, also influencing breeding.
* Plants sharing stats and attributes will tend to cross-breed more often.
*
* @return Attributes as an array of strings
*/
public String[] getAttributes() {
return new String[] {};
}
/**
* Determine the max crop size.
*
* Currently only used for texture allocation.
*/
public abstract int getMaxSize();
/**
* Amount of growth points needed to increase the plant's size.
* Default is 200 * tier.
*/
public int getGrowthDuration(ICropTile cropTile) {
return getProperties().getTier() * 200;
}
/**
* Check whether the plant can grow further.
*
* Consider:
* - Humidity, nutrients and air quality
* - Current size
* - Light level
* - Special biomes or conditions, accessible through crop.worldObj
*
* This method will be called upon empty upgraded crops to check whether a neighboring plant can cross onto it! Don't check if the size is greater than 0 and if the ID is real.
*
* @param cropTile reference to ICropTile
* @return Whether the crop can grow
*/
public boolean canGrow(ICropTile cropTile) {
return cropTile.getCurrentSize() < getMaxSize();
}
/**
* Calculate the influence for the plant to grow based on humidity, nutrients and air.
* Normal behavior is rating the three stats "normal", with each of them ranging from 0-30.
* Basic rule: Assume everything returns 10. All together must equal 30. Add the factors to your likings, for example (humidity*0.7)+(nutrients*0.9)+(air*1.4)
*
* Default is humidity + nutrients + air (no factors).
*
* @param crop reference to ICropTile
* @param humidity ground humidity, influenced by hydration
* @param nutrients nutrient quality in ground, based on fertilizers
* @param air air quality, influences by open gardens and less crops surrounding this one
* @return 0-30
*/
public int getWeightInfluences(ICropTile crop, int humidity, int nutrients, int air) {
return humidity + nutrients + air;
}
/**
* Used to determine whether the plant can crossbreed with another crop.
* Default is allow crossbreeding if the size is greater or equal than 3.
*
* @param crop crop to crossbreed with
*/
public boolean canCross(ICropTile crop) {
return crop.getCurrentSize() >= 3;
}
/**
* Called when the plant is rightclicked by a player.
* Default action is harvesting.
*
* Only called Serverside.
*
* @param cropTile reference to ICropTile
* @param player player rightclicking the crop
* @return Whether the plant has changed
*/
public boolean onRightClick(ICropTile cropTile, EntityPlayer player) {
return cropTile.performManualHarvest();
}
/**
* Use in Crop Harvester with insert Cropnalyzer to get best Output.
*
* @param cropTile reference to ICropTile
* @return need crop size for best output.
*/
public int getOptimalHarvestSize(ICropTile cropTile) {
return getMaxSize();
}
/**
* Check whether the crop can be harvested.
*
* @param cropTile reference to ICropTile
* @return Whether the crop can be harvested in its current state.
*/
public boolean canBeHarvested(ICropTile cropTile) {
return cropTile.getCurrentSize() == getMaxSize();
}
/**
* Base chance for dropping the plant's gains, specify values greater than 1 for multiple drops.
* Default is 0.95^tier.
*
* @return Chance to drop the gains
*/
public double dropGainChance() {
return Math.pow(0.95, getProperties().getTier());
}
/**
* Item obtained from harvesting the plant.
*
* @param crop reference to ICropTile
* @return Item obtained
*/
public abstract ItemStack getGain(ICropTile crop);
/**
* Get the size of the plant after harvesting.
* Default is 1.
*
* @param cropTile reference to ICropTile
* @return Plant size after harvesting
*/
public int getSizeAfterHarvest(ICropTile cropTile) {
return 1;
}
/**
* Called when the plant is left clicked by a player.
* Default action is picking the plant.
*
* Only called server side.
*
* @param cropTile reference to ICropTile
* @param player player left clicked the crop
* @return Whether the plant has changed
*/
public boolean onLeftClick(ICropTile cropTile, EntityPlayer player) {
return cropTile.pick();
}
/**
* Base chance for dropping seeds when the plant is picked.
* Default is 0.5*0.8^tier with a bigger chance for sizes greater than 2 and absolutely no chance for size 0.
*
* @param crop reference to ICropTile
* @return Chance to drop the seeds
*/
public float dropSeedChance(ICropTile crop) {
if (crop.getCurrentSize() == 1) return 0;
float base = 0.5F;
if (crop.getCurrentSize() == 2) base/=2F;
for (int i = 0; i < getProperties().getTier(); i++) {
base*=0.8;
}
return base;
}
/**
* Obtain seeds dropped when the plant is picked.
* Multiple drops of the returned ItemStack can occur.
* Default action is generating a seed from this crop.
*
* @param crop reference to ICropTile
* @return Seeds
*/
public ItemStack getSeeds(ICropTile crop) {
return crop.generateSeeds(crop.getCrop(), crop.getStatGrowth(), crop.getStatGain(), crop.getStatResistance(), crop.getScanLevel());
}
/**
* Called when a neighbor block to the crop has changed.
*
* @param crop reference to ICropTile
*/
public void onNeighbourChange(ICropTile crop) {
//
}
/**
* Check if the crop emits a redstone signal.
*
* @return Whether the crop emits a redstone signal.
*/
public boolean isRedstoneSignalEmitter(ICropTile cropTile) {
return false;
}
/***
* Get the emitted redstone signal strength.
*
* @return The redstone signal strength.
*/
public int getEmittedRedstoneSignal(ICropTile cropTile) {
return 0;
}
/**
* Called when the crop is destroyed.
*
* @param crop reference to ICropTile
*/
public void onBlockDestroyed(ICropTile crop) {
//
}
/**
* Get the light value emitted by the plant.
*
* @param crop reference to ICropTile
* @return Light value emitted
*/
public int getEmittedLight(ICropTile crop) {
return 0;
}
/**
* Default is true if the entity is an EntityLiving in jumping or sprinting state.
*
* @param crop reference to ICropTile
* @param entity entity colliding
* @return Whether trampling calculation should happen, return false if the plant is no longer valid.
*/
public boolean onEntityCollision(ICropTile crop, Entity entity) {
return (entity instanceof EntityLivingBase && entity.isSprinting());
}
/**
* Called every time the crop ticks.
* Should be called every 256 ticks or around 13 seconds.
*
* @param cropTile reference to ICropTile
*/
public void tick(ICropTile cropTile) {
// nothing by default
}
/**
* Check whether this plant spreads weed to surrounding tiles.
* Default is true if the plant has a high growth stat (or is weeds) and size greater or equal than 2.
*
* @param cropTile reference to ICropTile
* @return Whether the plant spreads weed
*/
public boolean isWeed(ICropTile cropTile) {
return cropTile.getCurrentSize() >= 2 &&
(cropTile.getCrop() == Crops.weed || cropTile.getStatGrowth() >= 24);
}
/**
* Retrieve the crop world.
* @param cropTile reference to ICropTile.
* @return The crop world object.
*/
public World getWorld(ICropTile cropTile) {
return cropTile.getWorld();
}
/**
* Retrieve the crop's unlocalized name.
* @return Unlocalized name
*/
public String getUnlocalizedName() {
return "crop." + getName() + ".name";
}
public List<ResourceLocation> getModelLocation() {
List<ResourceLocation> ret = new ArrayList<ResourceLocation>();
for (int i = 1; i <= getMaxSize(); i++) {
ret.add(new ResourceLocation(getOwner().toLowerCase(Locale.ENGLISH), "blocks/crop/"+getName()+"_"+i));
}
return ret;
}
}