Add BOP Plants (merged with foliage) deadgrass, desertgrass, desertsprouts, dunegrass, spectralfern, thorn, wildrice, cattail, rivercane, wildcarrot, tinycactus, witherwart, reed and root

This commit is contained in:
Cheeserolls 2015-04-11 21:43:31 +01:00
parent 87b76b4101
commit 890f009c49
76 changed files with 1133 additions and 400 deletions

View file

@ -124,7 +124,8 @@ public class BOPBlocks
public static Block tree_moss; public static Block tree_moss;
public static Block wisteria; public static Block wisteria;
public static Block foliage; public static Block plant_0;
public static Block plant_1;
public static Block double_foliage; public static Block double_foliage;
public static Block honey_block; public static Block honey_block;

View file

@ -0,0 +1,80 @@
/*******************************************************************************
* 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.HashMap;
import java.util.Map;
import com.google.common.base.Predicate;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.util.IStringSerializable;
public class BOPPlantEnums
{
public static enum AllPlants implements IStringSerializable {
SHORTGRASS, MEDIUMGRASS, BUSH, SPROUT, POISONIVY, BERRYBUSH, SHRUB, WHEATGRASS, DAMPGRASS, KORU, CLOVERPATCH, LEAFPILE, DEADLEAFPILE, DEADGRASS, DESERTGRASS, DESERTSPROUTS, DUNEGRASS, SPECTRALFERN, THORN, WILDRICE, CATTAIL, RIVERCANE, WILDCARROT, TINYCACTUS, WITHERWART, REED, ROOT;
@Override
public String getName() {
return this.name().toLowerCase();
}
@Override
public String toString()
{
return this.getName();
}
}
public static enum PlantsFilterType {
ALL;
public Predicate<AllPlants> getPredicate(final int pageNum, final int numPerPage)
{
// final PlantsFilterType filterType = this;
return new Predicate<AllPlants>()
{
@Override
public boolean apply(AllPlants plant)
{
return (plant.ordinal() >= (numPerPage * pageNum)) && (plant.ordinal() < (numPerPage * (pageNum+1)));
}
};
}
}
private static Map<Integer, PropertyEnum[]> propCache = new HashMap<Integer, PropertyEnum[]>();
public static PropertyEnum getVariantProperty(int pageNum, int numPerPage)
{
return getVariantProperty(pageNum, numPerPage, PlantsFilterType.ALL);
}
public static PropertyEnum getVariantProperty(int pageNum, int numPerPage, PlantsFilterType filterType)
{
// check length and make sure things are in bounds
int len = AllPlants.values().length;
int numPages = (int) Math.ceil( (double)len / numPerPage);
pageNum = Math.max(0, Math.min(pageNum, numPages - 1));
// look up the array of properties for pages of size numPerPage and the given filter - if it doesn't exist yet, create it
Integer index = new Integer(numPerPage * PlantsFilterType.values().length + filterType.ordinal() );
if (!propCache.containsKey(index)) {propCache.put(index, new PropertyEnum[numPages]);}
// look up the property for page pageNum - if it doesn't exist yet, create it
PropertyEnum[] propArr = propCache.get(index);
if (propArr[pageNum] == null)
{
propArr[pageNum] = PropertyEnum.create("variant", AllPlants.class, filterType.getPredicate(pageNum, numPerPage));
}
return propArr[pageNum];
}
}

View file

@ -25,6 +25,7 @@ public class BOPItems
public static Item gem; public static Item gem;
public static Item ash; public static Item ash;
public static Item berries; public static Item berries;
public static Item wildcarrots;
public static Item sacred_oak_door; public static Item sacred_oak_door;
public static Item cherry_door; public static Item cherry_door;

View file

@ -15,8 +15,8 @@ import net.minecraftforge.common.BiomeManager.BiomeType;
import biomesoplenty.api.biome.BOPBiome; import biomesoplenty.api.biome.BOPBiome;
import biomesoplenty.api.biome.generation.GeneratorStage; import biomesoplenty.api.biome.generation.GeneratorStage;
import biomesoplenty.api.block.BOPBlocks; import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.common.block.BlockFoliage; import biomesoplenty.api.block.BOPPlantEnums.AllPlants;
import biomesoplenty.common.block.BlockFoliage.FoliageType; import biomesoplenty.common.block.BlockBOPPlant;
import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.block.BlockGem;
import biomesoplenty.common.block.BlockGem.GemType; import biomesoplenty.common.block.BlockGem.GemType;
import biomesoplenty.common.world.feature.GeneratorGrass; import biomesoplenty.common.world.feature.GeneratorGrass;
@ -37,7 +37,7 @@ public class BiomeGenSteppe extends BOPBiome
this.spawnableCreatureList.add(new SpawnListEntry(EntityHorse.class, 5, 2, 6)); this.spawnableCreatureList.add(new SpawnListEntry(EntityHorse.class, 5, 2, 6));
this.addGenerator("dead_bushes", GeneratorStage.DEAD_BUSH, new GeneratorGrass(3, Blocks.deadbush.getDefaultState(), 4)); this.addGenerator("dead_bushes", GeneratorStage.DEAD_BUSH, new GeneratorGrass(3, Blocks.deadbush.getDefaultState(), 4));
this.addGenerator("grass", GeneratorStage.GRASS, new GeneratorGrass(15, BOPBlocks.foliage.getDefaultState().withProperty(BlockFoliage.VARIANT, FoliageType.SHORTGRASS))); this.addGenerator("grass", GeneratorStage.GRASS, new GeneratorGrass(15, BlockBOPPlant.getVariantState(AllPlants.SHORTGRASS)));
this.addGenerator("ruby", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, GemType.RUBY), 12, 4, 32)); this.addGenerator("ruby", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, GemType.RUBY), 12, 4, 32));
} }

View file

@ -15,9 +15,9 @@ import biomesoplenty.api.biome.BOPBiome;
import biomesoplenty.api.biome.generation.GeneratorStage; import biomesoplenty.api.biome.generation.GeneratorStage;
import biomesoplenty.api.biome.generation.GeneratorWeighted; import biomesoplenty.api.biome.generation.GeneratorWeighted;
import biomesoplenty.api.block.BOPBlocks; import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.common.block.BlockFoliage; import biomesoplenty.api.block.BOPPlantEnums.AllPlants;
import biomesoplenty.common.block.BlockBOPPlant;
import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.block.BlockGem;
import biomesoplenty.common.block.BlockFoliage.FoliageType;
import biomesoplenty.common.block.BlockGem.GemType; import biomesoplenty.common.block.BlockGem.GemType;
import biomesoplenty.common.world.feature.GeneratorFlora; import biomesoplenty.common.world.feature.GeneratorFlora;
import biomesoplenty.common.world.feature.GeneratorOreSingle; import biomesoplenty.common.world.feature.GeneratorOreSingle;
@ -44,8 +44,8 @@ public class BiomeGenThicket extends BOPBiome
//TODO: Add the rest of the generators, requires plant blocks //TODO: Add the rest of the generators, requires plant blocks
this.addGenerator("flowers", GeneratorStage.FLOWERS, new GeneratorFlora(5, Blocks.red_flower.getDefaultState())); this.addGenerator("flowers", GeneratorStage.FLOWERS, new GeneratorFlora(5, Blocks.red_flower.getDefaultState()));
//this.addGenerator("thorns", GeneratorStage.FLOWERS, new GeneratorFlora(55, BOPBlocks.foliage.getDefaultState().withProperty(BlockBOPPlant., FoliageType.LEAFPILE)); //this.addGenerator("thorns", GeneratorStage.FLOWERS, new GeneratorFlora(55, BOPBlocks.foliage.getDefaultState().withProperty(BlockBOPPlant., FoliageType.LEAFPILE));
this.addGenerator("leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(5, BOPBlocks.foliage.getDefaultState().withProperty(BlockFoliage.VARIANT, FoliageType.LEAFPILE))); this.addGenerator("leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(5, BlockBOPPlant.getVariantState(AllPlants.LEAFPILE)));
this.addGenerator("dead_leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(10, BOPBlocks.foliage.getDefaultState().withProperty(BlockFoliage.VARIANT, FoliageType.DEADLEAFPILE))); this.addGenerator("dead_leaf_piles", GeneratorStage.FLOWERS, new GeneratorFlora(10, BlockBOPPlant.getVariantState(AllPlants.DEADLEAFPILE)));
this.addGenerator("amber", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, GemType.AMBER), 12, 4, 32)); this.addGenerator("amber", GeneratorStage.SAND, new GeneratorOreSingle(BOPBlocks.gem_ore.getDefaultState().withProperty(BlockGem.VARIANT, GemType.AMBER), 12, 4, 32));
} }

View file

@ -0,0 +1,582 @@
/*******************************************************************************
* 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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.api.block.BOPPlantEnums;
import biomesoplenty.api.block.BOPPlantEnums.AllPlants;
import biomesoplenty.api.item.BOPItems;
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.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemShears;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.ColorizerGrass;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeColorHelper;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.IShearable;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
// TODO: shrub needs custom item texture
// TODO: double cattail
// TODO: placing reeds
// TODO: pick block?
public abstract class BlockBOPPlant extends BlockDecoration implements IShearable
{
// setup paged variant property
// All 4 meta bits available for VARIANT which means we can have sixteen per instance
public static final int VARIANTS_PER_PAGE = 16;
// child classes must implement to define their page number
abstract public int getPageNum();
// fetch the variant property for a given page
public static PropertyEnum getVariantProperty(int pageNum)
{
return BOPPlantEnums.getVariantProperty(pageNum, VARIANTS_PER_PAGE);
}
// fetch the current instance's variant property
public PropertyEnum getMyVariantProperty()
{
return getVariantProperty(getPageNum());
}
// get the meta bits from the variant
public int metaFromVariant(AllPlants plant)
{
return plant.ordinal() % VARIANTS_PER_PAGE;
}
// get the variant from meta bits (safely)
public AllPlants variantFromMeta(int meta)
{
int i = Math.max(0, Math.min(meta + (this.getPageNum() * VARIANTS_PER_PAGE), AllPlants.values().length));
return AllPlants.values()[i];
}
// store reference to each created instance, indexed by page num, so that later we can look up the right BlockFoliage instance for a particular variant
private static Map<Integer, BlockBOPPlant> instances = new HashMap<Integer, BlockBOPPlant>();
// get the BlockFoliage instance for the given variant
public static BlockBOPPlant getVariantBlock(AllPlants plant)
{
int pageNum = plant.ordinal() / VARIANTS_PER_PAGE;
BlockBOPPlant block = instances.get(pageNum);
if (block == null) {throw new IllegalArgumentException("No BlockFoliage instance created yet for page "+pageNum);}
return block;
}
// get the default block state for the given variant
public static IBlockState getVariantState(AllPlants plant)
{
BlockBOPPlant block = getVariantBlock(plant);
return block.getDefaultState().withProperty(block.getMyVariantProperty() , plant);
}
// get the item representation of the given variant
public static ItemStack getVariantItem(AllPlants plant, int howMany)
{
return new ItemStack(getVariantBlock(plant), howMany, getVariantBlock(plant).getMetaFromState(getVariantState(plant)));
}
public static ItemStack getVariantItem(AllPlants plant)
{
return getVariantItem(plant, 1);
}
@Override
protected BlockState createBlockState() {return new BlockState(this, new IProperty[] { getMyVariantProperty() });}
// implement IBOPBlock
@Override
public IProperty[] getPresetProperties() { return new IProperty[] { getMyVariantProperty() }; }
@Override
public IProperty[] getNonRenderingProperties() { return null; }
@Override
public String getStateName(IBlockState state)
{
AllPlants plant = (AllPlants) state.getValue(getMyVariantProperty());
switch (plant)
{
case WILDCARROT:
return plant.getName() + "_block";
default:
return plant.getName();
}
}
public BlockBOPPlant()
{
super();
// save a reference to this instance so that later we can look up the right BlockFoliage instance for a particular variant
instances.put(this.getPageNum(), this);
this.setDefaultState( this.blockState.getBaseState() );
}
// map from state to meta and vice verca
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(getMyVariantProperty(), variantFromMeta(meta));
}
@Override
public int getMetaFromState(IBlockState state)
{
return metaFromVariant((AllPlants) state.getValue(getMyVariantProperty()));
}
// get the items dropped when you bash the bush
@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
{
Random rand = world instanceof World ? ((World)world).rand : RANDOM;
// start with an empty stack
List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
// add items based on the VARIANT
AllPlants plant = (AllPlants) state.getValue(getMyVariantProperty());
switch (plant)
{
case SHORTGRASS: case MEDIUMGRASS: case WHEATGRASS: case DAMPGRASS:
if (rand.nextInt(8) == 0)
{
// 1 in 8 chance of getting a seed from this grass
ret.add(ForgeHooks.getGrassSeed(rand));
}
break;
case SPROUT:
if (rand.nextInt(50) == 0)
{
// in in 50 chance of getting a carrot or potato from SPROUT
ret.add(new ItemStack(rand.nextInt(2) == 0 ? Items.carrot : Items.potato));
}
break;
case KORU:
if (rand.nextInt(64) == 0)
{
// 1 in 64 change of getting a turnip seed from KORU
ret.add(new ItemStack(BOPItems.turnip_seeds));
}
break;
case BERRYBUSH:
// BERRYBUSH always drops berries
ret.add(new ItemStack(BOPItems.berries));
break;
case WILDRICE:
// wildrice drops itself only 1 in 5 times
if (rand.nextInt(5) == 0)
{
ret.add(getVariantItem(plant));
}
break;
case WILDCARROT:
ret.add(new ItemStack(BOPItems.wildcarrots));
break;
case CATTAIL: case RIVERCANE: case TINYCACTUS: case WITHERWART: case REED: case ROOT:
// these variants drop themselves as items
ret.add(getVariantItem(plant));
break;
default:
// the rest drop nothing
break;
}
return ret;
}
@Override
public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity tileentity)
{
super.harvestBlock(world, player, pos, state, tileentity);
boolean usingShears = (player.getCurrentEquippedItem() == null || !(player.getCurrentEquippedItem().getItem() instanceof ItemShears));
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
// suffer cactus damage if you harvest thorn without shears
case THORN:
if (!usingShears)
{
player.attackEntityFrom(DamageSource.cactus, 2);
}
break;
default:
break;
}
}
@Override
@SideOnly(Side.CLIENT)
public boolean addDestroyEffects(World world, BlockPos pos, net.minecraft.client.particle.EffectRenderer effectRenderer)
{
IBlockState state = world.getBlockState(pos);
Block block = state.getBlock();
// make sure the block at pos is actually this block (according to the comments in Block.addDestroyEffects, it might not be...)
if (block != this) {return false;}
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case WITHERWART:
byte n = 3;
for (byte i = 0; i < n; i++)
{
for (byte j = 0; j < n; j++)
{
for (byte k = 0; k < n; k++)
{
double x = pos.getX() + (i + 0.5D) / n;
double y = pos.getY() + (j + 0.5D) / n;
double z = pos.getZ() + (k + 0.5D) / n;
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0.0D, 0.0D, 0.0D);
}
}
}
break;
default:
break;
}
return false;
}
// TODO: comment these
@Override
@SideOnly(Side.CLIENT)
public int getBlockColor()
{
return ColorizerGrass.getGrassColor(0.5D, 1.0D);
}
@Override
@SideOnly(Side.CLIENT)
public int getRenderColor(IBlockState state)
{
return this.getBlockColor();
}
@Override
@SideOnly(Side.CLIENT)
public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass)
{
IBlockState state = worldIn.getBlockState(pos);
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case SHRUB: case LEAFPILE:
return BiomeColorHelper.getFoliageColorAtPos(worldIn, pos);
case DEADLEAFPILE:
return 0xFFFFFF;
default:
return BiomeColorHelper.getGrassColorAtPos(worldIn, pos);
}
}
// berrybush item should not be tinted, even though the model is
@Override
public int getItemRenderColor(IBlockState state, int tintIndex)
{
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case BERRYBUSH:
return 0xFFFFFF;
default:
return this.getRenderColor(state);
}
}
// different variants have different sizes
@Override
public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)
{
IBlockState state = worldIn.getBlockState(pos);
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case CLOVERPATCH: case LEAFPILE: case DEADLEAFPILE:
this.setBlockBoundsByRadiusAndHeight(0.5F, 0.015625F);
break;
case SHORTGRASS:
this.setBlockBounds(0.1F, 0F, 0.1F, 0.9F, 0.25F, 0.9F);
break;
case MEDIUMGRASS:
this.setBlockBounds(0.1F, 0F, 0.1F, 0.9F, 0.6F, 0.9F);
break;
case CATTAIL:
this.setBlockBoundsByRadiusAndHeight(0.375F, 1.0F);
break;
case TINYCACTUS:
// TODO: what on earth is this madness? Does it just cause some random scattering?
long i1 = pos.getX() * 3129871 ^ pos.getZ() * 116129781L ^ pos.getY();
i1 = i1 * i1 * 42317861L + i1 * 11L;
float d0 = (float)(((i1 >> 16 & 15L) / 15.0F - 0.5D) * 0.5D);
float d2 = (float)(((i1 >> 24 & 15L) / 15.0F - 0.5D) * 0.5D);
this.setBlockBounds(0.3F + d0, 0.0F, 0.3F + d2, 0.7F + d0, 0.4F, 0.7F + d2);
break;
case ROOT:
// roots hang from ceiling
this.setBlockBoundsByRadiusAndHeight(0.4F, 0.8F, true);
break;
default:
this.setBlockBoundsByRadiusAndHeight(0.4F, 0.8F);
break;
}
}
@Override
public boolean canBlockStay(World world, BlockPos pos, IBlockState state)
{
AllPlants plant = ((AllPlants) state.getValue(getMyVariantProperty()));
// roots hang down from above, all the others grow up from below
IBlockState adjacentBlockState = world.getBlockState(plant == AllPlants.ROOT ? pos.up() : pos.down());
Block adjacentBlock = adjacentBlockState.getBlock();
// TODO: the 1.7 code contained this line:
// if (block == Blocks.air && world.provider.dimensionId != -1 ? (world.getFullBlockLightValue(x, y, z) >= 8 || world.canBlockSeeTheSky(x, y, z)) : false) return false;
// which can be expressed a bit more clearly as this:
//
// boolean notInNether = !(world.provider instanceof net.minecraft.world.WorldProviderHell);
// boolean inAir = (groundBlock == Blocks.air);
// boolean wellLit = (world.getLight(pos) >= 8 || world.canSeeSky(pos));
// if (inAir && notInNether && wellLit) {return false;}
//
// That looks bonkers to me, so I'm ignoring it for now - need to ask the others
boolean onFertile = (adjacentBlock == Blocks.dirt || adjacentBlock == BOPBlocks.dirt || adjacentBlock == Blocks.mycelium || adjacentBlock == Blocks.grass);
boolean onDry = (adjacentBlock == BOPBlocks.hard_dirt || adjacentBlock == Blocks.hardened_clay || adjacentBlock == Blocks.sand || adjacentBlock == BOPBlocks.hard_sand || adjacentBlock == Blocks.soul_sand);
boolean onSand = (adjacentBlock == Blocks.sand || adjacentBlock == Blocks.soul_sand);
boolean onGrass = (adjacentBlock == Blocks.grass);
boolean onSpectralMoss = false;
if (adjacentBlock instanceof BlockBOPGrass)
{
switch ((BlockBOPGrass.BOPGrassType) adjacentBlockState.getValue(BlockBOPGrass.VARIANT))
{
case SPECTRAL_MOSS:
onSpectralMoss = true;
break;
case SMOLDERING:
break;
case OVERGROWN_NETHERRACK:
onFertile = true;
break;
case LOAMY: case SANDY: case SILTY: case ORIGIN: default:
onFertile = true;
onGrass = true;
break;
}
}
switch (plant)
{
case DEADGRASS: case DESERTGRASS: case TINYCACTUS:
return onDry;
case DESERTSPROUTS: case DUNEGRASS:
return onSand;
case SPECTRALFERN:
return onSpectralMoss;
case THORN:
return onFertile || onSand;
case CATTAIL:
boolean hasWater = (world.getBlockState(pos.add(-1, -1, 0)).getBlock().getMaterial() == Material.water || world.getBlockState(pos.add(1,-1,0)).getBlock().getMaterial() == Material.water || world.getBlockState(pos.add(0,-1,-1)).getBlock().getMaterial() == Material.water || world.getBlockState(pos.add(0,-1,1)).getBlock().getMaterial() == Material.water);
return onGrass && hasWater;
case RIVERCANE:
boolean onSelf = ( (adjacentBlock instanceof BlockBOPPlant) && ((AllPlants) adjacentBlockState.getValue(((BlockBOPPlant)adjacentBlock).getMyVariantProperty()) == AllPlants.RIVERCANE) );
return onSelf || onFertile;
case WITHERWART:
return (adjacentBlock == Blocks.soul_sand);
case REED:
// reed needs the ground block to be water, but the block below that to NOT be water
// TODO: reed is gonna have some trickiness with placing, implement as lily variation instead?
return (adjacentBlock == Blocks.water && world.getBlockState(pos.down().down()).getBlock() != Blocks.water);
default:
return onFertile;
}
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
// poison ivy throws up occasional spell particles
case POISONIVY:
if (rand.nextInt(32)==0)
{
worldIn.spawnParticle(EnumParticleTypes.SPELL_MOB, (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;
default:
break;
}
super.randomDisplayTick(worldIn, pos, state, rand);
}
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
super.updateTick(worldIn, pos, state, rand);
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case BUSH:
// every now and then berries grow on a bush
if (rand.nextInt(80) > 0 && worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
worldIn.setBlockState(pos, getVariantState(AllPlants.BERRYBUSH));
}
break;
default:
break;
}
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity)
{
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case POISONIVY:
// poison ivy poisons players who walk into it
if (entity instanceof EntityPlayer) {
((EntityLivingBase) entity).addPotionEffect(new PotionEffect(Potion.poison.id, 100));
}
break;
case THORN: case TINYCACTUS:
// thorns and tiny cacti harm players like a vanilla cactus unless the player is wearing leather boots and leather leggings
// TODO: should other types of armor protect from thorns?
if (entity instanceof EntityPlayer) {
InventoryPlayer inventory = ((EntityPlayer)entity).inventory;
boolean wearingLeatherBoots = (inventory.armorInventory[0] != null && inventory.armorInventory[0].getItem() == Items.leather_boots);
boolean wearingLeatherLeggings = (inventory.armorInventory[1] != null && inventory.armorInventory[1].getItem() == Items.leather_leggings);
if (!wearingLeatherBoots && !wearingLeatherLeggings)
{
entity.attackEntityFrom(DamageSource.cactus, 1);
}
}
break;
default:
break;
}
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
{
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case BERRYBUSH:
// an activated berry bush turns into a regular bush and drops a berry
worldIn.setBlockState(pos, getVariantState(AllPlants.BUSH));
EntityItem berries = new EntityItem(worldIn, (double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), new ItemStack(BOPItems.berries));
if (!worldIn.isRemote)
{
worldIn.spawnEntityInWorld(berries);
if (!(playerIn instanceof FakePlayer))
{
berries.onCollideWithPlayer(playerIn);
}
return true;
}
break;
default:
break;
}
return super.onBlockActivated(worldIn, pos, state, playerIn, side, hitX, hitY, hitZ);
}
@Override
public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) {
IBlockState state = world.getBlockState(pos);
switch ((AllPlants) state.getValue(getMyVariantProperty()))
{
case CATTAIL: case RIVERCANE: case WILDCARROT:
return false;
default:
return true;
}
}
@Override
public List<ItemStack> onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) {
// start with an empty stack
List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
// add items based on the VARIANT
AllPlants plant = ((AllPlants) world.getBlockState(pos).getValue(getMyVariantProperty()));
switch (plant)
{
case CATTAIL: case RIVERCANE: case TINYCACTUS: case WITHERWART: case REED: case ROOT:
// these items drop themselves as items when the block is broken (from getDrops), so we don't want to add anything else for using shears
break;
case BERRYBUSH:
// BERRYBUSH gives a regular bush when sheared (note this is in addition to the berry from getDrops)
IBlockState bush = getVariantState(AllPlants.BUSH);
ret.add(new ItemStack(bush.getBlock(), 1, this.getMetaFromState(bush)));
// ret.add(new ItemStack(BOPItems.berries, 1));
break;
default:
// for everything else, get the block as an item
ret.add(getVariantItem(plant));
break;
}
return ret;
}
// TODO: pickblock on carrot?
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* 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.block.properties.PropertyEnum;
public class BlockBOPPlant0 extends BlockBOPPlant {
public static final int PAGENUM = 0;
// create a static reference to this block's variant property
// this is for convenience, and for consistency with other Block classes
public static final PropertyEnum VARIANT = BlockBOPPlant.getVariantProperty(PAGENUM);
@Override
public int getPageNum() {return PAGENUM;}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* 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.block.properties.PropertyEnum;
public class BlockBOPPlant1 extends BlockBOPPlant {
public static final int PAGENUM = 1;
// create a static reference to this block's variant property
// this is for convenience, and for consistency with other Block classes
public static final PropertyEnum VARIANT = BlockBOPPlant.getVariantProperty(PAGENUM);
@Override
public int getPageNum() {return PAGENUM;}
}

View file

@ -1,360 +0,0 @@
/*******************************************************************************
* 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.List;
import java.util.Random;
import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.api.item.BOPItems;
import net.minecraft.block.Block;
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.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.IStringSerializable;
import net.minecraft.world.ColorizerGrass;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeColorHelper;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.IShearable;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockFoliage extends BlockDecoration implements IShearable
{
// add properties
public static enum FoliageType implements IStringSerializable
{
SHORTGRASS, MEDIUMGRASS, BUSH, SPROUT, POISONIVY, BERRYBUSH, SHRUB, WHEATGRASS, DAMPGRASS, KORU, CLOVERPATCH, LEAFPILE, DEADLEAFPILE;
@Override
public String getName()
{
return this.name().toLowerCase();
}
@Override
public String toString()
{
return this.getName();
}
};
public static final PropertyEnum VARIANT = PropertyEnum.create("variant", FoliageType.class);
@Override
protected BlockState createBlockState() {return new BlockState(this, new IProperty[] { VARIANT });}
// implement IBOPBlock
@Override
public IProperty[] getPresetProperties() { return new IProperty[] {VARIANT}; }
@Override
public IProperty[] getNonRenderingProperties() { return null; }
@Override
public String getStateName(IBlockState state)
{
return ((FoliageType) state.getValue(VARIANT)).getName();
}
public BlockFoliage()
{
super();
this.setDefaultState( this.blockState.getBaseState().withProperty(VARIANT, FoliageType.SHORTGRASS) );
}
// map from state to meta and vice verca
@Override
public IBlockState getStateFromMeta(int meta)
{
return this.getDefaultState().withProperty(VARIANT, FoliageType.values()[meta < FoliageType.values().length ? meta : 0]);
}
@Override
public int getMetaFromState(IBlockState state)
{
return ((FoliageType) state.getValue(VARIANT)).ordinal();
}
// get the items dropped when you bash the bush
@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
{
Random rand = world instanceof World ? ((World)world).rand : RANDOM;
// start with an empty stack
List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
// add items based on the VARIANT
switch ((FoliageType) state.getValue(VARIANT))
{
case SHORTGRASS: case MEDIUMGRASS: case WHEATGRASS: case DAMPGRASS:
if (rand.nextInt(8) == 0)
{
// 1 in 8 chance of getting a seed from this grass
ret.add(ForgeHooks.getGrassSeed(rand));
}
break;
case SPROUT:
if (rand.nextInt(50) == 0)
{
// in in 50 chance of getting a carrot or potato from SPROUT
ret.add(new ItemStack(rand.nextInt(2) == 0 ? Items.carrot : Items.potato));
}
break;
case KORU:
if (rand.nextInt(64) == 0)
{
// 1 in 64 change of getting a turnip seed from KORU
ret.add(new ItemStack(BOPItems.turnip_seeds));
}
case BERRYBUSH:
// BERRYBUSH always drops berries
ret.add(new ItemStack(BOPItems.berries));
default:
break;
}
return ret;
}
// TODO: comment these
@Override
@SideOnly(Side.CLIENT)
public int getBlockColor()
{
return ColorizerGrass.getGrassColor(0.5D, 1.0D);
}
@Override
@SideOnly(Side.CLIENT)
public int getRenderColor(IBlockState state)
{
return this.getBlockColor();
}
@Override
@SideOnly(Side.CLIENT)
public int colorMultiplier(IBlockAccess worldIn, BlockPos pos, int renderPass)
{
switch ((FoliageType) worldIn.getBlockState(pos).getValue(VARIANT))
{
case SHRUB: case LEAFPILE:
return BiomeColorHelper.getFoliageColorAtPos(worldIn, pos);
case DEADLEAFPILE:
return 0xFFFFFF;
default:
return BiomeColorHelper.getGrassColorAtPos(worldIn, pos);
}
}
// berrybush item should not be tinted, even though the model is
@Override
public int getItemRenderColor(IBlockState state, int tintIndex)
{
switch ((FoliageType) state.getValue(VARIANT))
{
case BERRYBUSH:
return 0xFFFFFF;
default:
return this.getRenderColor(state);
}
}
// different variants have different sizes
@Override
public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)
{
switch ((FoliageType) worldIn.getBlockState(pos).getValue(VARIANT))
{
case CLOVERPATCH: case LEAFPILE: case DEADLEAFPILE:
this.setBlockBoundsByRadiusAndHeight(0.5F, 0.015625F);
break;
case SHORTGRASS:
this.setBlockBounds(0.1F, 0F, 0.1F, 0.9F, 0.25F, 0.9F);
break;
case MEDIUMGRASS:
this.setBlockBounds(0.1F, 0F, 0.1F, 0.9F, 0.6F, 0.9F);
break;
default:
this.setBlockBoundsByRadiusAndHeight(0.4F, 0.8F);
break;
}
}
@Override
public boolean canBlockStay(World world, BlockPos pos, IBlockState state)
{
IBlockState groundState = world.getBlockState(pos.down());
Block groundBlock = groundState.getBlock();
// TODO: the 1.7 code contained this line:
// if (block == Blocks.air && world.provider.dimensionId != -1 ? (world.getFullBlockLightValue(x, y, z) >= 8 || world.canBlockSeeTheSky(x, y, z)) : false) return false;
// which can be expressed a bit more clearly as this:
//
// boolean notInNether = !(world.provider instanceof net.minecraft.world.WorldProviderHell);
// boolean inAir = (groundBlock == Blocks.air);
// boolean wellLit = (world.getLight(pos) >= 8 || world.canSeeSky(pos));
// if (inAir && notInNether && wellLit) {return false;}
//
// That looks bonkers to me, so I'm ignoring it for now - need to ask the others
boolean onFertile = (groundBlock == Blocks.dirt || groundBlock == BOPBlocks.dirt || groundBlock == Blocks.mycelium || groundBlock == Blocks.grass);
if (groundBlock instanceof BlockBOPGrass)
{
switch ((BlockBOPGrass.BOPGrassType) groundState.getValue(BlockBOPGrass.VARIANT))
{
case SPECTRAL_MOSS: case SMOLDERING:
break;
case OVERGROWN_NETHERRACK: case LOAMY: case SANDY: case SILTY: case ORIGIN: default:
onFertile = true;
break;
}
}
return onFertile;
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
switch ((FoliageType) state.getValue(VARIANT))
{
// poison ivy throws up occasional spell particles
case POISONIVY:
if (rand.nextInt(32)==0)
{
worldIn.spawnParticle(EnumParticleTypes.SPELL_MOB, (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;
default:
break;
}
super.randomDisplayTick(worldIn, pos, state, rand);
}
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
super.updateTick(worldIn, pos, state, rand);
switch ((FoliageType) state.getValue(VARIANT))
{
case BUSH:
// every now and then berries grow on a bush
if (rand.nextInt(80) > 0 && worldIn.getLightFromNeighbors(pos.up()) >= 9)
{
worldIn.setBlockState(pos, state.withProperty(VARIANT, FoliageType.BERRYBUSH));
}
break;
default:
break;
}
}
@Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity)
{
switch ((FoliageType) state.getValue(VARIANT))
{
case POISONIVY:
// poison ivy poisons players who walk into it
if (entity instanceof EntityPlayer) {
((EntityLivingBase) entity).addPotionEffect(new PotionEffect(Potion.poison.id, 100));
}
break;
default:
break;
}
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
{
switch ((FoliageType) state.getValue(VARIANT))
{
case BERRYBUSH:
// an activated berry bush turns into a regular bush and drops a berry
worldIn.setBlockState(pos, state.withProperty(VARIANT, FoliageType.BUSH));
EntityItem berries = new EntityItem(worldIn, (double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), new ItemStack(BOPItems.berries));
if (!worldIn.isRemote)
{
worldIn.spawnEntityInWorld(berries);
if (!(playerIn instanceof FakePlayer))
{
berries.onCollideWithPlayer(playerIn);
}
return true;
}
break;
default:
break;
}
return super.onBlockActivated(worldIn, pos, state, playerIn, side, hitX, hitY, hitZ);
}
@Override
public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) {
return true;
}
@Override
public List<ItemStack> onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) {
// start with an empty stack
List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
// add items based on the VARIANT
IBlockState state = world.getBlockState(pos);
switch ((FoliageType) state.getValue(VARIANT))
{
case BERRYBUSH:
// BERRYBUSH gives a regular bush and a berry when sheared
ret.add(new ItemStack(this, 1, this.getMetaFromState(this.getDefaultState().withProperty(VARIANT, FoliageType.BUSH))));
ret.add(new ItemStack(BOPItems.berries, 1));
break;
default:
// default is to get the block unaltered
ret.add(new ItemStack(this, 1, this.getMetaFromState(state)));
break;
}
return ret;
}
}

View file

@ -62,7 +62,8 @@ import biomesoplenty.common.block.BlockCoral;
import biomesoplenty.common.block.BlockCrystal; import biomesoplenty.common.block.BlockCrystal;
import biomesoplenty.common.block.BlockDoubleFoliage; import biomesoplenty.common.block.BlockDoubleFoliage;
import biomesoplenty.common.block.BlockFlesh; import biomesoplenty.common.block.BlockFlesh;
import biomesoplenty.common.block.BlockFoliage; import biomesoplenty.common.block.BlockBOPPlant0;
import biomesoplenty.common.block.BlockBOPPlant1;
import biomesoplenty.common.block.BlockFruit; import biomesoplenty.common.block.BlockFruit;
import biomesoplenty.common.block.BlockGem; import biomesoplenty.common.block.BlockGem;
import biomesoplenty.common.block.BlockGemOre; import biomesoplenty.common.block.BlockGemOre;
@ -220,7 +221,8 @@ public class ModBlocks
tree_moss = registerBlock( new BlockBOPVine(false), "tree_moss" ); tree_moss = registerBlock( new BlockBOPVine(false), "tree_moss" );
wisteria = registerBlock( new BlockBOPVine(false), "wisteria" ); wisteria = registerBlock( new BlockBOPVine(false), "wisteria" );
foliage = registerBlock( new BlockFoliage(), "foliage" ); plant_0 = registerBlock( new BlockBOPPlant0(), "plant_0" );
plant_1 = registerBlock( new BlockBOPPlant1(), "plant_1" );
double_foliage = registerBlock( new BlockDoubleFoliage(), "double_foliage" ); double_foliage = registerBlock( new BlockDoubleFoliage(), "double_foliage" );
honey_block = registerBlock( new BlockHoney(), "honey_block" ); honey_block = registerBlock( new BlockHoney(), "honey_block" );

View file

@ -8,20 +8,7 @@
package biomesoplenty.common.init; package biomesoplenty.common.init;
import static biomesoplenty.api.item.BOPItems.ash; import static biomesoplenty.api.item.BOPItems.*;
import static biomesoplenty.api.item.BOPItems.berries;
import static biomesoplenty.api.item.BOPItems.crystal_shard;
import static biomesoplenty.api.item.BOPItems.filled_honeycomb;
import static biomesoplenty.api.item.BOPItems.fleshchunk;
import static biomesoplenty.api.item.BOPItems.gem;
import static biomesoplenty.api.item.BOPItems.honeycomb;
import static biomesoplenty.api.item.BOPItems.mudball;
import static biomesoplenty.api.item.BOPItems.peach;
import static biomesoplenty.api.item.BOPItems.pear;
import static biomesoplenty.api.item.BOPItems.persimmon;
import static biomesoplenty.api.item.BOPItems.turnip;
import static biomesoplenty.api.item.BOPItems.turnip_seeds;
import static biomesoplenty.api.item.BOPItems.wading_boots;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,6 +51,7 @@ public class ModItems
gem = registerItem(new ItemGem(), "gem"); gem = registerItem(new ItemGem(), "gem");
ash = registerItem(new Item(), "ash"); ash = registerItem(new Item(), "ash");
berries = registerItem(new ItemFood(1, 0.1F, false), "berries"); berries = registerItem(new ItemFood(1, 0.1F, false), "berries");
wildcarrots = registerItem(new ItemFood(3, 0.5F, false), "wildcarrots");
// armor // armor
// TODO: do we really want durability of -1? does that mean it lasts forever? // TODO: do we really want durability of -1? does that mean it lasts forever?

View file

@ -1,5 +0,0 @@
{
"variants": {
"normal": { "model": "biomesoplenty:ash_block" }
}
}

View file

@ -1,5 +0,0 @@
{
"variants": {
"normal": { "model": "biomesoplenty:ash_block" }
}
}

View file

@ -12,6 +12,9 @@
"variant=koru": { "model": "biomesoplenty:koru" }, "variant=koru": { "model": "biomesoplenty:koru" },
"variant=cloverpatch": { "model": "biomesoplenty:cloverpatch" }, "variant=cloverpatch": { "model": "biomesoplenty:cloverpatch" },
"variant=leafpile": { "model": "biomesoplenty:leafpile" }, "variant=leafpile": { "model": "biomesoplenty:leafpile" },
"variant=deadleafpile": { "model": "biomesoplenty:deadleafpile" } "variant=deadleafpile": { "model": "biomesoplenty:deadleafpile" },
"variant=deadgrass": { "model": "biomesoplenty:deadgrass" },
"variant=desertgrass": { "model": "biomesoplenty:desertgrass" },
"variant=desertsprouts": { "model": "biomesoplenty:desertsprouts" }
} }
} }

View file

@ -0,0 +1,15 @@
{
"variants": {
"variant=dunegrass": { "model": "biomesoplenty:dunegrass" },
"variant=spectralfern": { "model": "biomesoplenty:spectralfern" },
"variant=thorn": { "model": "biomesoplenty:thorn" },
"variant=wildrice": { "model": "biomesoplenty:wildrice" },
"variant=cattail": { "model": "biomesoplenty:cattail" },
"variant=rivercane": { "model": "biomesoplenty:rivercane" },
"variant=wildcarrot": { "model": "biomesoplenty:wildcarrot_block" },
"variant=tinycactus": { "model": "biomesoplenty:tinycactus" },
"variant=witherwart": { "model": "biomesoplenty:witherwart" },
"variant=reed": { "model": "biomesoplenty:reed" },
"variant=root": { "model": "biomesoplenty:root" }
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,6 +3,6 @@
"textures": { "textures": {
"colored": "biomesoplenty:blocks/shrub_branch", "colored": "biomesoplenty:blocks/shrub_branch",
"greyscale": "biomesoplenty:blocks/shrub", "greyscale": "biomesoplenty:blocks/shrub",
"particle": "biomesoplenty:blocks/shrub_branch" "particle": "biomesoplenty:blocks/shrub"
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -0,0 +1,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/cattail"
},
"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

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -0,0 +1,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/deadgrass"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/desertgrass"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/desertsprouts"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/dunegrass"
},
"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

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -0,0 +1,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/reed"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/rivercane"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/root"
},
"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

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -0,0 +1,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/spectralfern"
},
"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

@ -16,3 +16,4 @@
} }
} }
} }

View file

@ -0,0 +1,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/thorn"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/tinycactus"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/wildcarrot"
},
"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/wildcarrots"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/wildrice"
},
"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,19 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "biomesoplenty:blocks/witherwart"
},
"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 ]
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B