New Plant API that allows for custom plants/soils.

This commit is contained in:
LexManos 2012-09-20 19:53:43 -07:00
parent c3f9fed484
commit 28d2460611
12 changed files with 452 additions and 16 deletions

View File

@ -0,0 +1,12 @@
package net.minecraftforge.common;
public enum EnumPlantType
{
Plains,
Desert,
Beach,
Cave,
Water,
Nether,
Crop
}

View File

@ -11,8 +11,8 @@ public class ForgeVersion
public static final int majorVersion = 4;
//This number is incremented every official release, and reset every Minecraft version
public static final int minorVersion = 1;
//This number is incremented every time a interface changes, and reset every Minecraft version
public static final int revisionVersion = 3;
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
public static final int revisionVersion = 4;
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
public static final int buildVersion = 0;

View File

@ -0,0 +1,10 @@
package net.minecraftforge.common;
import net.minecraft.src.World;
public interface IPlantable
{
public EnumPlantType getPlantType(World world, int x, int y, int z);
public int getPlantID(World world, int x, int y, int z);
public int getPlantMetadata(World world, int x, int y, int z);
}

View File

@ -1,6 +1,6 @@
--- ../src_base/common/net/minecraft/src/Block.java
+++ ../src_work/common/net/minecraft/src/Block.java
@@ -2,11 +2,23 @@
@@ -2,11 +2,21 @@
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
@ -9,9 +9,7 @@
import java.util.List;
import java.util.Random;
+import net.minecraftforge.common.ForgeHooks;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.*;
+import static net.minecraftforge.common.ForgeDirection.*;
+
public class Block
@ -24,7 +22,7 @@
/**
* used as foreach item, if item.tab = current tab, display it on the screen
*/
@@ -279,6 +291,7 @@
@@ -279,6 +289,7 @@
lightOpacity[par1] = this.isOpaqueCube() ? 255 : 0;
canBlockGrass[par1] = !par2Material.getCanBlockGrass();
}
@ -32,7 +30,7 @@
}
/**
@@ -417,9 +430,10 @@
@@ -417,9 +428,10 @@
return this.needsRandomTick;
}
@ -44,7 +42,7 @@
}
/**
@@ -442,7 +456,7 @@
@@ -442,7 +454,7 @@
*/
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -53,7 +51,7 @@
}
@SideOnly(Side.CLIENT)
@@ -452,7 +466,7 @@
@@ -452,7 +464,7 @@
*/
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -62,7 +60,7 @@
}
@SideOnly(Side.CLIENT)
@@ -621,8 +635,7 @@
@@ -621,8 +633,7 @@
*/
public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5)
{
@ -72,7 +70,7 @@
}
/**
@@ -640,18 +653,13 @@
@@ -640,18 +651,13 @@
{
if (!par1World.isRemote)
{
@ -95,7 +93,7 @@
}
}
}
@@ -985,7 +993,7 @@
@@ -985,7 +991,7 @@
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
par2EntityPlayer.addExhaustion(0.025F);
@ -104,7 +102,7 @@
{
ItemStack var8 = this.createStackedBlock(par6);
@@ -1249,4 +1257,717 @@
@@ -1249,4 +1255,797 @@
canBlockGrass[0] = true;
StatList.initBreakableStats();
}
@ -820,5 +818,85 @@
+ public boolean addBlockDestroyEffects(World world, int x, int y, int z, int meta, EffectRenderer effectRenderer)
+ {
+ return false;
+ }
+
+ /**
+ * Determines if this block can support the passed in plant, allowing it to be planted and grow.
+ * Some examples:
+ * Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water
+ * Cacti checks if its a cacti, or if its sand
+ * Nether types check for soul sand
+ * Crops check for tilled soil
+ * Caves check if it's a colid surface
+ * Plains check if its grass or dirt
+ * Water check if its still water
+ *
+ * @param world The current world
+ * @param x X Position
+ * @param y Y Position
+ * @param z Z position
+ * @param direction The direction relative to the given position the plant wants to be, typically its UP
+ * @param plant The plant that wants to check
+ * @return True to allow the plant to be planted/stay.
+ */
+ public boolean canSustainPlant(World world, int x, int y, int z, ForgeDirection direction, IPlantable plant)
+ {
+ int plantID = plant.getPlantID(world, x, y + 1, z);
+ EnumPlantType plantType = plant.getPlantType(world, x, y + 1, z);
+
+ if (plantID == cactus.blockID && blockID == cactus.blockID)
+ {
+ return true;
+ }
+
+ if (plantID == reed.blockID && blockID == reed.blockID)
+ {
+ return true;
+ }
+
+ if (plant instanceof BlockFlower && ((BlockFlower)plant).canThisPlantGrowOnThisBlockID(blockID))
+ {
+ return true;
+ }
+
+ switch (plantType)
+ {
+ case Desert: return blockID == sand.blockID;
+ case Nether: return blockID == slowSand.blockID;
+ case Crop: return blockID == tilledField.blockID;
+ case Cave: return isBlockSolidOnSide(world, x, y, z, UP);
+ case Plains: return blockID == grass.blockID || blockID == dirt.blockID;
+ case Water: return world.getBlockMaterial(x, y, z) == Material.water && world.getBlockMetadata(x, y, z) == 0;
+ case Beach:
+ boolean isBeach = (blockID == Block.grass.blockID || blockID == Block.dirt.blockID || blockID == Block.sand.blockID);
+ boolean hasWater = (world.getBlockMaterial(x - 1, y - 1, z ) == Material.water ||
+ world.getBlockMaterial(x + 1, y - 1, z ) == Material.water ||
+ world.getBlockMaterial(x, y - 1, z - 1) == Material.water ||
+ world.getBlockMaterial(x, y - 1, z + 1) == Material.water);
+ return isBeach && hasWater;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if this soil is fertile, typically this means that growth rates
+ * of plants on this soil will be slightly sped up.
+ * Only vanilla case is tilledField when it is within range of water.
+ *
+ * @param world The current world
+ * @param x X Position
+ * @param y Y Position
+ * @param z Z position
+ * @return True if the soil should be considered fertile.
+ */
+ public boolean isFertile(World world, int x, int y, int z)
+ {
+ if (blockID == tilledField.blockID)
+ {
+ return world.getBlockMetadata(x, y, z) > 0;
+ }
+
+ return false;
+ }
}

View File

@ -0,0 +1,47 @@
--- ../src_base/common/net/minecraft/src/BlockCactus.java
+++ ../src_work/common/net/minecraft/src/BlockCactus.java
@@ -4,7 +4,11 @@
import cpw.mods.fml.common.asm.SideOnly;
import java.util.Random;
-public class BlockCactus extends Block
+import net.minecraftforge.common.EnumPlantType;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.IPlantable;
+
+public class BlockCactus extends Block implements IPlantable
{
protected BlockCactus(int par1, int par2)
{
@@ -143,7 +147,7 @@
else
{
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
- return var5 == Block.cactus.blockID || var5 == Block.sand.blockID;
+ return blocksList[var5] != null && blocksList[var5].canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this);
}
}
@@ -154,4 +158,22 @@
{
par5Entity.attackEntityFrom(DamageSource.cactus, 1);
}
+
+ @Override
+ public EnumPlantType getPlantType(World world, int x, int y, int z)
+ {
+ return EnumPlantType.Desert;
+ }
+
+ @Override
+ public int getPlantID(World world, int x, int y, int z)
+ {
+ return blockID;
+ }
+
+ @Override
+ public int getPlantMetadata(World world, int x, int y, int z)
+ {
+ return -1;
+ }
}

View File

@ -1,15 +1,32 @@
--- ../src_base/common/net/minecraft/src/BlockCrops.java
+++ ../src_work/common/net/minecraft/src/BlockCrops.java
@@ -2,6 +2,8 @@
@@ -2,7 +2,11 @@
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
+
+import java.util.ArrayList;
import java.util.Random;
+
+import net.minecraftforge.common.ForgeDirection;
public class BlockCrops extends BlockFlower
@@ -138,25 +140,27 @@
{
@@ -84,11 +88,11 @@
int var19 = par1World.getBlockId(var17, par3 - 1, var18);
float var20 = 0.0F;
- if (var19 == Block.tilledField.blockID)
+ if (blocksList[var19] != null && blocksList[var19].canSustainPlant(par1World, var17, par3 - 1, var18, ForgeDirection.UP, this))
{
var20 = 1.0F;
- if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0)
+ if (blocksList[var19].isFertile(par1World, var17, par3 - 1, var18))
{
var20 = 3.0F;
}
@@ -138,25 +142,27 @@
public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
{
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0);

View File

@ -0,0 +1,22 @@
--- ../src_base/common/net/minecraft/src/BlockFarmland.java
+++ ../src_work/common/net/minecraft/src/BlockFarmland.java
@@ -3,6 +3,9 @@
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
import java.util.Random;
+
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.IPlantable;
public class BlockFarmland extends Block
{
@@ -97,7 +100,8 @@
{
int var8 = par1World.getBlockId(var6, par3 + 1, var7);
- if (var8 == Block.crops.blockID || var8 == Block.melonStem.blockID || var8 == Block.pumpkinStem.blockID)
+ Block plant = blocksList[var8];
+ if (plant instanceof IPlantable && canSustainPlant(par1World, par2, par3, par4, ForgeDirection.UP, (IPlantable)plant))
{
return true;
}

View File

@ -0,0 +1,69 @@
--- ../src_base/common/net/minecraft/src/BlockFlower.java
+++ ../src_work/common/net/minecraft/src/BlockFlower.java
@@ -2,7 +2,12 @@
import java.util.Random;
-public class BlockFlower extends Block
+import net.minecraftforge.common.EnumPlantType;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.IPlantable;
+import static net.minecraftforge.common.EnumPlantType.*;
+
+public class BlockFlower extends Block implements IPlantable
{
protected BlockFlower(int par1, int par2, Material par3Material)
{
@@ -24,7 +29,7 @@
*/
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
- return super.canPlaceBlockAt(par1World, par2, par3, par4) && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4));
+ return super.canPlaceBlockAt(par1World, par2, par3, par4) && canBlockStay(par1World, par2, par3 - 1, par4);
}
/**
@@ -68,7 +73,9 @@
*/
public boolean canBlockStay(World par1World, int par2, int par3, int par4)
{
- return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 || par1World.canBlockSeeTheSky(par2, par3, par4)) && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4));
+ Block soil = blocksList[par1World.getBlockId(par2, par3 - 1, par4)];
+ return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 || par1World.canBlockSeeTheSky(par2, par3, par4)) &&
+ (soil != null && soil.canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this));
}
/**
@@ -104,4 +111,32 @@
{
return 1;
}
+
+ @Override
+ public EnumPlantType getPlantType(World world, int x, int y, int z)
+ {
+ if (blockID == crops.blockID ) return Crop;
+ if (blockID == deadBush.blockID ) return Desert;
+ if (blockID == waterlily.blockID ) return Water;
+ if (blockID == mushroomRed.blockID ) return Cave;
+ if (blockID == mushroomBrown.blockID) return Cave;
+ if (blockID == netherStalk.blockID ) return Nether;
+ if (blockID == sapling.blockID ) return Plains;
+ if (blockID == melonStem.blockID ) return Crop;
+ if (blockID == pumpkinStem.blockID ) return Crop;
+ if (blockID == tallGrass.blockID ) return Plains;
+ return Plains;
+ }
+
+ @Override
+ public int getPlantID(World world, int x, int y, int z)
+ {
+ return blockID;
+ }
+
+ @Override
+ public int getPlantMetadata(World world, int x, int y, int z)
+ {
+ return world.getBlockMetadata(x, y, z);
+ }
}

View File

@ -0,0 +1,20 @@
--- ../src_base/common/net/minecraft/src/BlockMushroom.java
+++ ../src_work/common/net/minecraft/src/BlockMushroom.java
@@ -1,6 +1,8 @@
package net.minecraft.src;
import java.util.Random;
+
+import net.minecraftforge.common.ForgeDirection;
public class BlockMushroom extends BlockFlower
{
@@ -94,7 +96,7 @@
if (par3 >= 0 && par3 < 256)
{
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
- return var5 == Block.mycelium.blockID || par1World.getFullBlockLightValue(par2, par3, par4) < 13 && this.canThisPlantGrowOnThisBlockID(var5);
+ return var5 == Block.mycelium.blockID || par1World.getFullBlockLightValue(par2, par3, par4) < 13 && canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this);
}
else
{

View File

@ -0,0 +1,37 @@
--- ../src_base/common/net/minecraft/src/BlockReed.java
+++ ../src_work/common/net/minecraft/src/BlockReed.java
@@ -4,7 +4,10 @@
import cpw.mods.fml.common.asm.SideOnly;
import java.util.Random;
-public class BlockReed extends Block
+import net.minecraftforge.common.EnumPlantType;
+import net.minecraftforge.common.IPlantable;
+
+public class BlockReed extends Block implements IPlantable
{
protected BlockReed(int par1, int par2)
{
@@ -135,4 +138,22 @@
{
return Item.reed.shiftedIndex;
}
+
+ @Override
+ public EnumPlantType getPlantType(World world, int x, int y, int z)
+ {
+ return EnumPlantType.Beach;
+ }
+
+ @Override
+ public int getPlantID(World world, int x, int y, int z)
+ {
+ return blockID;
+ }
+
+ @Override
+ public int getPlantMetadata(World world, int x, int y, int z)
+ {
+ return world.getBlockMetadata(x, y, z);
+ }
}

View File

@ -0,0 +1,88 @@
--- ../src_base/common/net/minecraft/src/BlockStem.java
+++ ../src_work/common/net/minecraft/src/BlockStem.java
@@ -2,7 +2,11 @@
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
+
+import java.util.ArrayList;
import java.util.Random;
+
+import net.minecraftforge.common.ForgeDirection;
public class BlockStem extends BlockFlower
{
@@ -96,7 +100,8 @@
int var11 = par1World.getBlockId(var9, par3 - 1, var10);
- if (par1World.getBlockId(var9, par3, var10) == 0 && (var11 == Block.tilledField.blockID || var11 == Block.dirt.blockID || var11 == Block.grass.blockID))
+ boolean isSoil = (blocksList[var11] != null && blocksList[var11].canSustainPlant(par1World, var9, par3 - 1, var10, ForgeDirection.UP, this));
+ if (par1World.getBlockId(var9, par3, var10) == 0 && (isSoil || var11 == Block.dirt.blockID || var11 == Block.grass.blockID))
{
par1World.setBlockWithNotify(var9, par3, var10, this.fruitType.blockID);
}
@@ -132,11 +137,11 @@
int var19 = par1World.getBlockId(var17, par3 - 1, var18);
float var20 = 0.0F;
- if (var19 == Block.tilledField.blockID)
+ if (blocksList[var19] != null && blocksList[var19].canSustainPlant(par1World, var17, par3 - 1, var18, ForgeDirection.UP, this))
{
var20 = 1.0F;
- if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0)
+ if (blocksList[var19].isFertile(par1World, var17, par3 - 1, var18))
{
var20 = 3.0F;
}
@@ -236,35 +241,22 @@
public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
{
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
-
- if (!par1World.isRemote)
- {
- Item var8 = null;
-
- if (this.fruitType == Block.pumpkin)
+ }
+
+ @Override
+ public ArrayList<ItemStack> getBlockDropped(World world, int x, int y, int z, int metadata, int fortune)
+ {
+ ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
+
+ for (int i = 0; i < 3; i++)
+ {
+ if (world.rand.nextInt(15) <= metadata)
{
- var8 = Item.pumpkinSeeds;
+ ret.add(new ItemStack(fruitType == pumpkin ? Item.pumpkinSeeds : Item.melonSeeds));
}
-
- if (this.fruitType == Block.melon)
- {
- var8 = Item.melonSeeds;
- }
-
- for (int var9 = 0; var9 < 3; ++var9)
- {
- if (par1World.rand.nextInt(15) <= par5)
- {
- float var10 = 0.7F;
- float var11 = par1World.rand.nextFloat() * var10 + (1.0F - var10) * 0.5F;
- float var12 = par1World.rand.nextFloat() * var10 + (1.0F - var10) * 0.5F;
- float var13 = par1World.rand.nextFloat() * var10 + (1.0F - var10) * 0.5F;
- EntityItem var14 = new EntityItem(par1World, (double)((float)par2 + var11), (double)((float)par3 + var12), (double)((float)par4 + var13), new ItemStack(var8));
- var14.delayBeforeCanPickup = 10;
- par1World.spawnEntityInWorld(var14);
- }
- }
- }
+ }
+
+ return ret;
}
/**

View File

@ -0,0 +1,36 @@
--- ../src_base/common/net/minecraft/src/ItemSeeds.java
+++ ../src_work/common/net/minecraft/src/ItemSeeds.java
@@ -1,6 +1,9 @@
package net.minecraft.src;
-public class ItemSeeds extends Item
+import net.minecraftforge.common.EnumPlantType;
+import net.minecraftforge.common.IPlantable;
+
+public class ItemSeeds extends Item implements IPlantable
{
/**
* The type of block this seed turns into (wheat or pumpkin stems for instance)
@@ -48,4 +51,22 @@
return false;
}
}
+
+ @Override
+ public EnumPlantType getPlantType(World world, int x, int y, int z)
+ {
+ return (blockType == Block.netherStalk.blockID ? EnumPlantType.Nether : EnumPlantType.Crop);
+ }
+
+ @Override
+ public int getPlantID(World world, int x, int y, int z)
+ {
+ return blockType;
+ }
+
+ @Override
+ public int getPlantMetadata(World world, int x, int y, int z)
+ {
+ return 0;
+ }
}