Merge pull request #435 from cheeserolls/cheeserolls

Cheeserolls
This commit is contained in:
Adubbz 2015-03-26 17:45:17 +11:00
commit 72a9aefe19
41 changed files with 1143 additions and 19 deletions

2
.gitignore vendored
View file

@ -7,3 +7,5 @@
/.settings/ /.settings/
/.classpath /.classpath
/.project /.project
# OS generated files
*.DS_Store

View file

@ -28,4 +28,8 @@ public class BOPBlocks
public static Block mushroom; public static Block mushroom;
public static Block planks; public static Block planks;
public static Block stone; public static Block stone;
public static Block mud;
public static Block turnip_block;
public static Block flesh;
public static Block grass;
} }

View file

@ -0,0 +1,269 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.api.block;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.IGrowable;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
// TODO: BOPPlant should probably implement IPlantable instead?
public abstract class BOPCrops extends BOPPlant implements IGrowable, IPlantable
{
public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 7);
protected BOPCrops()
{
// start with age=0
this.setDefaultState(this.blockState.getBaseState().withProperty(AGE, Integer.valueOf(0)));
// one-quarter height
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
// general crop stuff
this.setTickRandomly(true);
this.setHardness(0.0F);
this.setStepSound(Block.soundTypeGrass);
// copied from Vanilla BlockCrops class
this.disableStats();
}
// crops should always be in the centre of the block
@Override
public Block.EnumOffsetType getOffsetType()
{
return Block.EnumOffsetType.NONE;
}
// grow crops +1 age on random ticks if the light is good enough
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
super.updateTick(worldIn, pos, state, rand);
if (worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
int i = ((Integer)state.getValue(AGE)).intValue();
if (i < 7)
{
float f = getGrowthChance(this, worldIn, pos);
if (rand.nextInt((int)(25.0F / f) + 1) == 0)
{
worldIn.setBlockState(pos, state.withProperty(AGE, Integer.valueOf(i + 1)), 2);
}
}
}
}
// grow crops a random amount from 2 to 5 - I think this is only called when bonemeal is applied to the crop
public void grow(World worldIn, BlockPos pos, IBlockState state)
{
int i = ((Integer)state.getValue(AGE)).intValue() + MathHelper.getRandomIntegerInRange(worldIn.rand, 2, 5);
if (i > 7)
{
i = 7;
}
worldIn.setBlockState(pos, state.withProperty(AGE, Integer.valueOf(i)), 2);
}
@Override
public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
this.grow(worldIn, pos, state);
}
// return a multiplier reflecting the chance of crop growth
// TODO: some pretty arcane looking rules in here - need to decipher them - and simplify perhaps
protected static float getGrowthChance(Block blockIn, World worldIn, BlockPos pos)
{
float f = 1.0F;
BlockPos blockpos1 = pos.down();
for (int i = -1; i <= 1; ++i)
{
for (int j = -1; j <= 1; ++j)
{
float f1 = 0.0F;
IBlockState iblockstate = worldIn.getBlockState(blockpos1.add(i, 0, j));
if (iblockstate.getBlock().canSustainPlant(worldIn, blockpos1.add(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)blockIn))
{
f1 = 1.0F;
if (iblockstate.getBlock().isFertile(worldIn, blockpos1.add(i, 0, j)))
{
f1 = 3.0F;
}
}
if (i != 0 || j != 0)
{
f1 /= 4.0F;
}
f += f1;
}
}
BlockPos blockpos2 = pos.north();
BlockPos blockpos3 = pos.south();
BlockPos blockpos4 = pos.west();
BlockPos blockpos5 = pos.east();
boolean flag = blockIn == worldIn.getBlockState(blockpos4).getBlock() || blockIn == worldIn.getBlockState(blockpos5).getBlock();
boolean flag1 = blockIn == worldIn.getBlockState(blockpos2).getBlock() || blockIn == worldIn.getBlockState(blockpos3).getBlock();
if (flag && flag1)
{
f /= 2.0F;
}
else
{
boolean flag2 = blockIn == worldIn.getBlockState(blockpos4.north()).getBlock() || blockIn == worldIn.getBlockState(blockpos5.north()).getBlock() || blockIn == worldIn.getBlockState(blockpos5.south()).getBlock() || blockIn == worldIn.getBlockState(blockpos4.south()).getBlock();
if (flag2)
{
f /= 2.0F;
}
}
return f;
}
// whether or not the crop can remain planted at its current position
@Override
public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state)
{
return (worldIn.getLight(pos) >= 8 || worldIn.canSeeSky(pos)) && worldIn.getBlockState(pos.down()).getBlock().canSustainPlant(worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this);
}
// the item to return as the seed for this crop - child classes must override
protected abstract Item getSeed();
// the item to return as the harvest for this crop - child classes must implement
protected abstract Item getCrop();
// fortune tools have no effect on crop yield
@Override
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
{
super.dropBlockAsItemWithChance(worldIn, pos, state, chance, 0);
}
// if the plant is mature, drop the crop, otherwise drop seeds
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
return ((Integer)state.getValue(AGE)).intValue() == 7 ? this.getCrop() : this.getSeed();
}
// whether or not the crop can still grow further (and so bonemeal can be used)
@Override
public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient)
{
return ((Integer)state.getValue(AGE)).intValue() < 7;
}
// always returns true - so presumably this just says the block in general is capable of receiving bonemeal, although a specific instance might not if it's fully grown
@Override
public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
return true;
}
@Override
@SideOnly(Side.CLIENT)
public Item getItem(World worldIn, BlockPos pos)
{
return this.getSeed();
}
// map state to meta - simple choice here meta=age
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(AGE, Integer.valueOf(meta));
}
// map state to meta - simple choice here meta=age
@Override
public int getMetaFromState(IBlockState state)
{
return ((Integer)state.getValue(AGE)).intValue();
}
@Override
protected BlockState createBlockState()
{
return new BlockState(this, new IProperty[] {AGE});
}
// default behavior when the block is broken is to call getItemDropped() which yields 1 seed item or 1 crop item depending on the crop's maturity
// modify this so that mature crops in addition might also yield some seeds
@Override
public java.util.List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
{
java.util.List<ItemStack> ret = super.getDrops(world, pos, state, fortune);
int age = ((Integer)state.getValue(AGE)).intValue();
Random rand = world instanceof World ? ((World)world).rand : new Random();
if (age >= 7)
{
int k = 3 + fortune;
for (int i = 0; i < k; ++i)
{
if (rand.nextInt(15) <= age)
{
ret.add(new ItemStack(this.getSeed(), 1, 0));
}
}
}
return ret;
}
@Override
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos)
{
return net.minecraftforge.common.EnumPlantType.Crop;
// note the value 'Crop' prevents these blocks from being placed anywhere other than farmland - see Block.canSustainPlant
}
@Override
public IBlockState getPlant(IBlockAccess world, BlockPos pos)
{
IBlockState state = world.getBlockState(pos);
if (state.getBlock() != this) return getDefaultState();
return state;
}
// BOPBlock uses getMetaFromState as default value for damageDropped - this is unhelpful for crops where the meta value is the crop age - use 0 as default instead
@Override
public int damageDropped(IBlockState state)
{
return 0;
}
}

View file

@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.api.item;
import net.minecraft.item.Item;
public class BOPItems
{
public static Item fleshchunk;
public static Item mudball;
public static Item turnip;
public static Item turnip_seeds;
}

View file

@ -0,0 +1,284 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.common.block;
import java.util.Random;
import biomesoplenty.api.block.BOPBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.IStringSerializable;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockBOPGrass extends BOPBlock
{
public static final PropertyEnum VARIANT_PROP = PropertyEnum.create("variant", BOPGrassType.class);
public BlockBOPGrass()
{
super(Material.grass);
this.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT_PROP, BOPGrassType.SPECTRALMOSS));
this.setHardness(0.6F);
this.setHarvestLevel("shovel", 0); // TODO: this means that ONLY a shovel can harvest this block... correct?
this.setStepSound(Block.soundTypeGrass);
this.setTickRandomly(true);
}
@Override
public IBlockState getStateFromMeta(int meta)
{
// only one property to worry about, the variant, so just map [0 => SPECTRALMOSS, 1 => SMOLDERINGGRASS]
return this.getDefaultState().withProperty(VARIANT_PROP, BOPGrassType.values()[meta]);
}
@Override
public int getMetaFromState(IBlockState state)
{
// only one property to worry about, the variant, so just map [0 => SPECTRALMOSS, 1 => SMOLDERINGGRASS]
return ((BOPGrassType) state.getValue(VARIANT_PROP)).ordinal();
}
@Override
protected BlockState createBlockState()
{
return new BlockState(this, new IProperty[] { VARIANT_PROP });
}
@Override
public IProperty[] getPresetProperties()
{
return new IProperty[] { VARIANT_PROP };
}
@Override
public String getStateName(IBlockState state, boolean fullName)
{
return ((BOPGrassType) state.getValue(VARIANT_PROP)).getName();
}
@Override
public boolean isFireSource(World world, BlockPos pos, EnumFacing side)
{
IBlockState state = world.getBlockState(pos);
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
// spectralmoss burns from below in the end
// TODO: 1.7 code had dimension=-1 here - check -1 corresponds to end
case SPECTRALMOSS:
if ((world.provider instanceof net.minecraft.world.WorldProviderEnd) && side == EnumFacing.UP) {return true;}
break;
// smolderinggrass always burns
case SMOLDERINGGRASS:
return false;
}
return super.isFireSource(world, pos, side);
}
@Override
public IBlockState onBlockPlaced(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
IBlockState state = this.getStateFromMeta(meta);
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
// spectralmoss makes a hideous noise and throws a big fuss of particles around when placed in the nether
case SPECTRALMOSS:
if (world.provider instanceof net.minecraft.world.WorldProviderHell)
{
world.playSound(pos.getX(), pos.getY(), pos.getZ(), "mob.ghast.death", 20.0F, (float)Math.random() * 0.1F, true);
for (int l = 0; l < 8; ++l)
{
world.spawnParticle(EnumParticleTypes.FLAME, (double)pos.getX() + Math.random(), (double)pos.getY() + Math.random(), (double)pos.getZ() + Math.random(), 0.0D, 0.0D, 0.0D);
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (double)pos.getX() + Math.random(), (double)pos.getY() + Math.random(), (double)pos.getZ() + Math.random(), 0.0D, 0.0D, 0.0D);
}
}
break;
case SMOLDERINGGRASS:
break;
}
return state;
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
case SPECTRALMOSS:
break;
// smolderinggrass throws up random flame and smoke particles
case SMOLDERINGGRASS:
if (rand.nextInt(4)==0)
{
worldIn.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + 1.1F), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D);
}
if (rand.nextInt(6)==0)
{
worldIn.spawnParticle(EnumParticleTypes.FLAME, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + 1.1F), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D);
}
break;
}
super.randomDisplayTick(worldIn, pos, state, rand);
}
@Override
@SideOnly(Side.CLIENT)
public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) {
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
case SPECTRALMOSS:
// spectral moss in the nether catches on fire and turns to smoldering grass
// elsewhere it should behave like grass spreading to nearby end_stone blocks
if (world.provider instanceof net.minecraft.world.WorldProviderHell)
{
world.setBlockState(pos.up(), Blocks.fire.getDefaultState()); // might need to set fire AGE value... not sure
world.setBlockState(pos, this.getDefaultState().withProperty(VARIANT_PROP, BOPGrassType.SMOLDERINGGRASS));
}
else
{
// if this block is covered, then turn it back to end_stone (IE kill the moss)
if (world.getLightFromNeighbors(pos.up()) < 4 && world.getBlockState(pos.up()).getBlock().getLightOpacity(world, pos.up()) > 2)
{
world.setBlockState(pos, Blocks.end_stone.getDefaultState());
}
else
{
// if there's enough light from above, spread the moss randomly to nearby end_stone blocks
if (world.getLightFromNeighbors(pos.up()) >= 9)
{
for (int i = 0; i < 4; ++i) // try 4 times
{
// pick a random nearby position
BlockPos pos1 = pos.add(rand.nextInt(3) - 1, rand.nextInt(5) - 3, rand.nextInt(3) - 1);
Block blockAbove = world.getBlockState(pos1.up()).getBlock();
IBlockState iblockstate1 = world.getBlockState(pos1);
// if there's enough light and it isn't covered, turn it to moss
if (iblockstate1.getBlock() == Blocks.end_stone && world.getLightFromNeighbors(pos1.up()) >= 4 && blockAbove.getLightOpacity(world, pos1.up()) <= 2)
{
world.setBlockState(pos1, this.getDefaultState().withProperty(VARIANT_PROP, BOPGrassType.SPECTRALMOSS) );
}
}
}
}
}
break;
case SMOLDERINGGRASS:
break;
}
}
@Override
public AxisAlignedBB getCollisionBoundingBox(World world, BlockPos pos, IBlockState state)
{
float heightOffset = 0.0F;
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
case SPECTRALMOSS:
break;
// smoldering grass is a tiny bit lower than usual
case SMOLDERINGGRASS:
heightOffset = 0.02F;
break;
}
return new AxisAlignedBB((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), (double) (pos.getX() + 1), (double) ((float) (pos.getY() + 1) - heightOffset), (double) (pos.getZ() + 1));
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity)
{
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
case SPECTRALMOSS:
break;
// smoldering grass sets you on fire for 2 seconds
case SMOLDERINGGRASS:
entity.setFire(2);
break;
}
}
// you need a silk touch tool to pick up grass-like blocks - by default they drop the corresponding 'dirt' type
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
case SPECTRALMOSS:
return Item.getItemFromBlock(Blocks.end_stone);
case SMOLDERINGGRASS:
return Item.getItemFromBlock(Blocks.dirt);
}
return super.getItemDropped(state, rand, fortune);
}
// goes hand in hand with getItemDropped() above to determine precisely what is dropped
@Override
public int damageDropped(IBlockState state)
{
switch ((BOPGrassType) state.getValue(VARIANT_PROP))
{
// end stone doesn't have any variants
case SPECTRALMOSS:
return 0;
// make sure dirt item dropped is plain dirt (not any other variant)
case SMOLDERINGGRASS:
return BlockDirt.DirtType.DIRT.getMetadata();
}
return super.damageDropped(state);
}
// enum representing the 2 variants of grass
public static enum BOPGrassType implements IStringSerializable
{
SPECTRALMOSS, SMOLDERINGGRASS;
@Override
public String getName()
{
switch(this)
{
case SPECTRALMOSS:
return "spectral_moss";
case SMOLDERINGGRASS:
return "smoldering_grass_block";
}
return this.name().toLowerCase();
}
@Override
public String toString()
{
return getName();
}
}
}

View file

@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.common.block;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.Item;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import biomesoplenty.api.block.BOPBlock;
import biomesoplenty.api.item.BOPItems;
public class BlockFlesh extends BOPBlock
{
public BlockFlesh() {
super(Material.sponge);
this.setHardness(0.4F);
this.setStepSound(Block.soundTypeGravel);
}
@Override
public AxisAlignedBB getCollisionBoundingBox(World world, BlockPos pos, IBlockState state)
{
// 7/8 height
float heightOffset = 0.125F;
return new AxisAlignedBB((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), (double) (pos.getX() + 1), (double) ((float) (pos.getY() + 1) - heightOffset), (double) (pos.getZ() + 1));
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
// randomly throw up some particles so it looks like the flesh is bubbling
super.randomDisplayTick(worldIn, pos, state, rand);
if (rand.nextInt(4)==0)
{
worldIn.spawnParticle(EnumParticleTypes.BLOCK_CRACK, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + 1.1F), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D, new int[] {Block.getStateId(state)});
}
if (rand.nextInt(12)==0)
{
worldIn.spawnParticle(EnumParticleTypes.BLOCK_CRACK, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + 1.1F), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D, new int[] {Block.getStateId(state)});
}
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity)
{
if (entity instanceof EntityPlayer) {
InventoryPlayer inventory = ((EntityPlayer)entity).inventory;
// TODO: implement wadingBoots
//if (inventory.armorInventory[0] != null && inventory.armorInventory[0].getItem() == BOPItems.wadingBoots) {
// return;
//}
}
// slow you slightly
entity.motionX *= 0.9D;
entity.motionZ *= 0.9D;
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
return BOPItems.fleshchunk;
}
@Override
public int quantityDropped(Random random)
{
return random.nextInt(3);
}
}

View file

@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.common.block;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.Item;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.IStringSerializable;
import net.minecraft.world.World;
import biomesoplenty.api.block.BOPBlock;
import biomesoplenty.api.item.BOPItems;
public class BlockMud extends BOPBlock
{
public static final PropertyEnum VARIANT_PROP = PropertyEnum.create("variant", MudType.class);
public BlockMud()
{
super(Material.sand);
this.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT_PROP, MudType.MUD));
this.setHardness(0.6F);
this.setStepSound(Block.soundTypeSand);
}
@Override
public AxisAlignedBB getCollisionBoundingBox(World world, BlockPos pos, IBlockState state)
{
float heightOffset = 0.0F;
switch ((MudType) state.getValue(VARIANT_PROP))
{
// sink a little when standing on mud
case MUD:
heightOffset = 0.35F;
break;
// no bounding box at all for quicksand - you're supposed to sink into it
case QUICKSAND:
return null;
}
return new AxisAlignedBB((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), (double) (pos.getX() + 1), (double) ((float) (pos.getY() + 1) - heightOffset), (double) (pos.getZ() + 1));
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity)
{
if (entity instanceof EntityPlayer) {
InventoryPlayer inventory = ((EntityPlayer)entity).inventory;
// TODO: implement wadingBoots
//if (inventory.armorInventory[0] != null && inventory.armorInventory[0].getItem() == BOPItems.wadingBoots) {
// return;
//}
}
switch ((MudType) state.getValue(VARIANT_PROP))
{
// mud slows you greatly
case MUD:
entity.motionX *= 0.1D;
entity.motionZ *= 0.1D;
break;
// quicksand behaves like being trapped in a spider web
case QUICKSAND:
entity.setInWeb();
break;
}
}
@Override
public IBlockState getStateFromMeta(int meta)
{
// only one property to worry about, the variant, so just map [0 => MUD, 1 => QUICKSAND]
return this.getDefaultState().withProperty(VARIANT_PROP, MudType.values()[meta]);
}
@Override
public int getMetaFromState(IBlockState state)
{
// only one property to worry about, the variant, so just map [0 => MUD, 1 => QUICKSAND]
return ((MudType) state.getValue(VARIANT_PROP)).ordinal();
}
@Override
protected BlockState createBlockState()
{
return new BlockState(this, new IProperty[] { VARIANT_PROP });
}
@Override
public IProperty[] getPresetProperties()
{
return new IProperty[] { VARIANT_PROP };
}
@Override
public String getStateName(IBlockState state, boolean fullName)
{
return ((MudType) state.getValue(VARIANT_PROP)).getName();
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
switch ((MudType) state.getValue(VARIANT_PROP))
{
case MUD:
return BOPItems.mudball;
case QUICKSAND:
break;
}
return super.getItemDropped(state,rand,fortune);
}
@Override
public int quantityDropped(Random random)
{
return 4;
}
// enum representing the 2 variants of mud
public static enum MudType implements IStringSerializable
{
MUD, QUICKSAND;
@Override
public String getName()
{
return this.name().toLowerCase();
}
@Override
public String toString()
{
return getName();
}
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.common.block;
import net.minecraft.item.Item;
import biomesoplenty.api.block.BOPCrops;
import biomesoplenty.api.item.BOPItems;
public class BlockTurnip extends BOPCrops
{
public BlockTurnip()
{
this.setCreativeTab(null);
}
@Override
protected Item getSeed()
{
return BOPItems.turnip_seeds;
}
@Override
protected Item getCrop()
{
return BOPItems.turnip;
}
}

View file

@ -21,6 +21,7 @@ import biomesoplenty.api.block.BOPBlock;
import biomesoplenty.common.block.BlockAsh; import biomesoplenty.common.block.BlockAsh;
import biomesoplenty.common.block.BlockBOPFlower; import biomesoplenty.common.block.BlockBOPFlower;
import biomesoplenty.common.block.BlockBOPFlower2; import biomesoplenty.common.block.BlockBOPFlower2;
import biomesoplenty.common.block.BlockBOPGrass;
import biomesoplenty.common.block.BlockBOPLog; import biomesoplenty.common.block.BlockBOPLog;
import biomesoplenty.common.block.BlockBOPLog2; import biomesoplenty.common.block.BlockBOPLog2;
import biomesoplenty.common.block.BlockBOPLog3; import biomesoplenty.common.block.BlockBOPLog3;
@ -34,6 +35,9 @@ import biomesoplenty.common.block.BlockCoral;
import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.block.BlockGem;
import biomesoplenty.common.block.BlockGemOre; import biomesoplenty.common.block.BlockGemOre;
import biomesoplenty.common.block.BlockHive; import biomesoplenty.common.block.BlockHive;
import biomesoplenty.common.block.BlockMud;
import biomesoplenty.common.block.BlockTurnip;
import biomesoplenty.common.block.BlockFlesh;
import biomesoplenty.common.handler.GuiEventHandler; import biomesoplenty.common.handler.GuiEventHandler;
import biomesoplenty.common.item.ItemBlockWithVariants; import biomesoplenty.common.item.ItemBlockWithVariants;
import biomesoplenty.common.util.block.BlockStateUtils; import biomesoplenty.common.util.block.BlockStateUtils;
@ -59,6 +63,10 @@ public class ModBlocks
mushroom = registerBlock(new BlockBOPMushroom(), "mushroom"); mushroom = registerBlock(new BlockBOPMushroom(), "mushroom");
planks = registerBlock(new BlockBOPPlanks(), "planks"); planks = registerBlock(new BlockBOPPlanks(), "planks");
stone = registerBlock(new BlockBOPStone(), "stone"); stone = registerBlock(new BlockBOPStone(), "stone");
mud = registerBlock(new BlockMud(), "mud");
turnip_block = registerBlock(new BlockTurnip(), "turnip_block");
flesh = registerBlock(new BlockFlesh(), "flesh");
grass = registerBlock(new BlockBOPGrass(), "grass");
} }
private static Block registerBlock(BOPBlock block, String name) private static Block registerBlock(BOPBlock block, String name)
@ -94,4 +102,5 @@ public class ModBlocks
return block; return block;
} }
} }

View file

@ -8,10 +8,34 @@
package biomesoplenty.common.init; package biomesoplenty.common.init;
import static biomesoplenty.api.item.BOPItems.*;
import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.common.item.ItemMudball;
import biomesoplenty.common.util.inventory.CreativeTabBOP;
import biomesoplenty.core.BiomesOPlenty;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemSeedFood;
import net.minecraft.item.ItemSeeds;
import net.minecraftforge.fml.common.registry.GameRegistry;
public class ModItems public class ModItems
{ {
public static void init() public static void init()
{ {
fleshchunk = registerItem(new Item(),"fleshchunk");
mudball = registerItem(new ItemMudball(),"mudball");
turnip_seeds = registerItem(new ItemSeeds(BOPBlocks.turnip_block, Blocks.farmland),"turnip_seeds");
turnip = registerItem(new ItemFood(3, 0.4F, false),"turnip");
} }
}
private static Item registerItem(Item item, String name)
{
item.setUnlocalizedName(name).setCreativeTab(CreativeTabBOP.instance);
GameRegistry.registerItem(item,name);
BiomesOPlenty.proxy.registerItemForMeshing(item,name);
return item;
}
}

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright 2014, the Biomes O' Plenty Team
*
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
*
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
******************************************************************************/
package biomesoplenty.common.item;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntitySnowball;
import net.minecraft.stats.StatList;
import net.minecraft.world.World;
public class ItemMudball extends Item
{
public ItemMudball()
{
this.maxStackSize = 16;
}
// throw a mudball on right click
@Override
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
{
if (!playerIn.capabilities.isCreativeMode)
{
--itemStackIn.stackSize;
}
worldIn.playSoundAtEntity(playerIn, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
if (!worldIn.isRemote)
{
// TODO: implement EntityMudball worldIn.spawnEntityInWorld(new EntityMudball(worldIn, playerIn));
worldIn.spawnEntityInWorld(new EntitySnowball(worldIn, playerIn));
}
playerIn.triggerAchievement(StatList.objectUseStats[Item.getIdFromItem(this)]);
return itemStackIn;
}
}

View file

@ -48,8 +48,11 @@ public class BiomesOPlenty
configDirectory = new File(event.getModConfigurationDirectory(), "biomesoplenty"); configDirectory = new File(event.getModConfigurationDirectory(), "biomesoplenty");
ModConfiguration.init(configDirectory); ModConfiguration.init(configDirectory);
ModItems.init();
// setup blocks before items, because some items need to reference blocks in their constructors (eg seeds)
ModBlocks.init(); ModBlocks.init();
ModItems.init();
ModBiomes.init(); ModBiomes.init();
ModHandlers.init(); ModHandlers.init();
ModConfiguration.initEnd(configDirectory); ModConfiguration.initEnd(configDirectory);

View file

@ -19,6 +19,7 @@ import biomesoplenty.client.util.ModelHelper;
public class ClientProxy extends CommonProxy public class ClientProxy extends CommonProxy
{ {
private static ArrayList<ModelEntry> blocksToRegister = new ArrayList(); private static ArrayList<ModelEntry> blocksToRegister = new ArrayList();
private static ArrayList<ItemEntry> itemsToRegister = new ArrayList();
@Override @Override
public void registerRenderers() public void registerRenderers()
@ -27,6 +28,12 @@ public class ClientProxy extends CommonProxy
{ {
ModelHelper.registerBlock(modelEntry.block, modelEntry.metadata, BiomesOPlenty.MOD_ID + ":" + modelEntry.name); ModelHelper.registerBlock(modelEntry.block, modelEntry.metadata, BiomesOPlenty.MOD_ID + ":" + modelEntry.name);
} }
for (ItemEntry itemEntry : itemsToRegister)
{
ModelHelper.registerItem(itemEntry.item, 0, BiomesOPlenty.MOD_ID + ":" + itemEntry.name);
}
} }
@Override @Override
@ -40,6 +47,12 @@ public class ClientProxy extends CommonProxy
{ {
blocksToRegister.add(new ModelEntry(block, metadata, name)); blocksToRegister.add(new ModelEntry(block, metadata, name));
} }
@Override
public void registerItemForMeshing(Item item, String name)
{
itemsToRegister.add(new ItemEntry(item, name));
}
private static class ModelEntry private static class ModelEntry
{ {
@ -54,4 +67,16 @@ public class ClientProxy extends CommonProxy
this.name = name; this.name = name;
} }
} }
private static class ItemEntry
{
public Item item;
public String name;
public ItemEntry(Item item, String name)
{
this.item = item;
this.name = name;
}
}
} }

View file

@ -9,18 +9,16 @@
package biomesoplenty.core; package biomesoplenty.core;
import biomesoplenty.api.block.BOPBlock; import biomesoplenty.api.block.BOPBlock;
import net.minecraft.block.Block;
import net.minecraft.item.Item; import net.minecraft.item.Item;
public class CommonProxy public class CommonProxy
{ {
public void registerRenderers() public void registerRenderers() {}
{
}
public void addVariantName(Item item, String... names) {} public void addVariantName(Item item, String... names) {}
public void registerBlockForMeshing(BOPBlock block, int metadata, String name) public void registerBlockForMeshing(BOPBlock block, int metadata, String name) {}
{
} public void registerItemForMeshing(Item item, String name) {}
}
}

View file

@ -1,5 +1,5 @@
{ {
"variants": { "variants": {
"variant=flesh": { "model": "biomesoplenty:flesh" } "normal": { "model": "biomesoplenty:flesh" }
} }
} }

View file

@ -0,0 +1,6 @@
{
"variants": {
"variant=mud": { "model": "biomesoplenty:mud" },
"variant=quicksand": { "model": "biomesoplenty:quicksand" }
}
}

View file

@ -0,0 +1,12 @@
{
"variants": {
"age=0": { "model": "biomesoplenty:turnip_stage0" },
"age=1": { "model": "biomesoplenty:turnip_stage0" },
"age=2": { "model": "biomesoplenty:turnip_stage1" },
"age=3": { "model": "biomesoplenty:turnip_stage1" },
"age=4": { "model": "biomesoplenty:turnip_stage2" },
"age=5": { "model": "biomesoplenty:turnip_stage2" },
"age=6": { "model": "biomesoplenty:turnip_stage2" },
"age=7": { "model": "biomesoplenty:turnip_stage3" }
}
}

View file

@ -11,8 +11,8 @@ tile.bone_segment.small.name=Small Bone Segment
tile.bone_segment.medium.name=Medium Bone Segment tile.bone_segment.medium.name=Medium Bone Segment
tile.bone_segment.large.name=Large Bone Segment tile.bone_segment.large.name=Large Bone Segment
tile.bopGrass.spectral_moss.name=Spectral Moss tile.grass.spectral_moss.name=Spectral Moss
tile.bopGrass.smoldering_grass_block.name=Smoldering Grass Block tile.grass.smoldering_grass_block.name=Smoldering Grass Block
tile.coral.pink.name=Pink Coral tile.coral.pink.name=Pink Coral
tile.coral.orange.name=Orange Coral tile.coral.orange.name=Orange Coral
@ -91,6 +91,9 @@ tile.log3.hell_bark.name=Hell Bark Wood
tile.log3.jacaranda.name=Jacaranda Wood tile.log3.jacaranda.name=Jacaranda Wood
tile.log4.mahogany.name=Mahogany Wood tile.log4.mahogany.name=Mahogany Wood
tile.mud.mud.name=Mud
tile.mud.quicksand.name=Quicksand
tile.mushroom.toadstool.name=Toadstool tile.mushroom.toadstool.name=Toadstool
tile.mushroom.portobello.name=Portobello tile.mushroom.portobello.name=Portobello
tile.mushroom.blue_milk_cap.name=Blue Milk Cap tile.mushroom.blue_milk_cap.name=Blue Milk Cap
@ -120,3 +123,10 @@ tile.stone.siltstone.name=Siltstone
tile.stone.polished_siltstone.name=Polished Siltstone tile.stone.polished_siltstone.name=Polished Siltstone
tile.stone.shale.name=Shale tile.stone.shale.name=Shale
tile.stone.polished_shale.name=Polished Shale tile.stone.polished_shale.name=Polished Shale
tile.turnip_block.name=Turnip
item.fleshchunk.name=Chunk of Flesh
item.mudball.name=Mud Ball
item.turnip.name=Turnip
item.turnip_seeds.name=Turnip Seeds

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "biomesoplenty:blocks/mud"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "biomesoplenty:blocks/quicksand"
}
}

View file

@ -1,9 +1,9 @@
{ {
"parent": "block/cube_bottom_top", "parent": "block/cube_bottom_top",
"textures": { "textures": {
"particle": "biomesoplenty:blocks/smoldering_grass_block_bottom", "particle": "biomesoplenty:blocks/smoldering_grass_bottom",
"bottom": "biomesoplenty:blocks/smoldering_grass_block_bottom", "bottom": "biomesoplenty:blocks/smoldering_grass_bottom",
"top": "biomesoplenty:blocks/smoldering_grass_block_top", "top": "biomesoplenty:blocks/smoldering_grass_top",
"side": "biomesoplenty:blocks/smoldering_grass_block_side" "side": "biomesoplenty:blocks/smoldering_grass_side"
} }
} }

View file

@ -0,0 +1,6 @@
{
"parent": "block/crop",
"textures": {
"crop": "biomesoplenty:blocks/turnip_stage_0"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/crop",
"textures": {
"crop": "biomesoplenty:blocks/turnip_stage_1"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/crop",
"textures": {
"crop": "biomesoplenty:blocks/turnip_stage_2"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/crop",
"textures": {
"crop": "biomesoplenty:blocks/turnip_stage_3"
}
}

View file

@ -0,0 +1,18 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:items/fleshchunk"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -0,0 +1,10 @@
{
"parent": "biomesoplenty:block/mud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -0,0 +1,18 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:items/mudball"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -0,0 +1,10 @@
{
"parent": "biomesoplenty:block/quicksand",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -0,0 +1,18 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:items/turnip"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -0,0 +1,18 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:items/turnip_seeds"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -2.5 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B