diff --git a/src/main/java/com/minelittlepony/unicopia/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/UBlocks.java index e150d89a..0121dce5 100644 --- a/src/main/java/com/minelittlepony/unicopia/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/UBlocks.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia; +import com.minelittlepony.unicopia.block.BlockAlfalfa; import com.minelittlepony.unicopia.block.BlockCloud; import com.minelittlepony.unicopia.block.BlockCloudAnvil; import com.minelittlepony.unicopia.block.BlockCloudSlab; @@ -21,7 +22,10 @@ public class UBlocks { public static final BlockCloudAnvil anvil = new BlockCloudAnvil(Unicopia.MODID, "anvil"); + public static final BlockAlfalfa alfalfa = new BlockAlfalfa(Unicopia.MODID, "alfalfa"); + static void registerBlocks(IForgeRegistry registry) { - registry.registerAll(cloud, stairsCloud, cloud_double_slab, cloud_slab, mist_door, anvil); + registry.registerAll(cloud, stairsCloud, cloud_double_slab, cloud_slab, mist_door, anvil, + alfalfa); } } diff --git a/src/main/java/com/minelittlepony/unicopia/UItems.java b/src/main/java/com/minelittlepony/unicopia/UItems.java index f287556b..0f8e26e2 100644 --- a/src/main/java/com/minelittlepony/unicopia/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/UItems.java @@ -15,10 +15,12 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; import net.minecraft.init.Enchantments; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemDoor; +import net.minecraft.item.ItemSeeds; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.item.crafting.IRecipe; @@ -75,6 +77,10 @@ public class UItems { public static final ItemOfHolding bag_of_holding = new ItemOfHolding(Unicopia.MODID, "bag_of_holding"); + public static final Item alfalfa_seeds = new ItemSeeds(UBlocks.alfalfa, Blocks.FARMLAND) + .setTranslationKey("alfalfa_seeds") + .setRegistryName(Unicopia.MODID, "alfalfa_seeds"); + static void registerItems(IForgeRegistry registry) { RegistryLockSpinner.unlock(Item.REGISTRY); @@ -84,7 +90,8 @@ public class UItems { registry.registerAll(cloud_spawner, dew_drop, cloud_matter, cloud_block, cloud_stairs, cloud_slab, mist_door, anvil, - bag_of_holding, spell, curse); + bag_of_holding, spell, curse, + alfalfa_seeds); if (UClient.isClientSide()) { registerAllVariants(apple, apple.getVariants()); @@ -99,6 +106,7 @@ public class UItems { registerAllVariants(bag_of_holding, "bag_of_holding"); registerAllVariants(spell, "gem"); registerAllVariants(curse, "corrupted_gem"); + registerAllVariants(alfalfa_seeds, "alfalfa_seeds"); } registerFuels(); diff --git a/src/main/java/com/minelittlepony/unicopia/block/BlockAlfalfa.java b/src/main/java/com/minelittlepony/unicopia/block/BlockAlfalfa.java new file mode 100644 index 00000000..b4051754 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/BlockAlfalfa.java @@ -0,0 +1,269 @@ +package com.minelittlepony.unicopia.block; + +import java.util.Random; + +import com.minelittlepony.unicopia.UItems; + +import net.minecraft.block.BlockCrops; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; + +public class BlockAlfalfa extends BlockCrops { + + public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 5); + public static final PropertyEnum HALF = PropertyEnum.create("half", Half.class); + + private static final AxisAlignedBB[] BOUNDS = new AxisAlignedBB[] { + new AxisAlignedBB(0, 0, 0, 1, 0.1, 1), + new AxisAlignedBB(0, 0, 0, 1, 0.2, 1), + new AxisAlignedBB(0, 0, 0, 1, 0.4, 1), + new AxisAlignedBB(0, 0, 0, 1, 0.6, 1), + new AxisAlignedBB(0, 0, 0, 1, 0.8, 1), + new AxisAlignedBB(0, 0, 0, 1, 1, 1), + new AxisAlignedBB(0, 0, 0, 1, 1.2, 1), + new AxisAlignedBB(0, 0, 0, 1, 1.4, 1), + new AxisAlignedBB(0, 0, 0, 1, 1.6, 1), + new AxisAlignedBB(0, 0, 0, 1, 1.8, 1), + new AxisAlignedBB(0, 0, 0, 1, 2, 1), + new AxisAlignedBB(0, 0, 0, 1, 2.2, 1), + new AxisAlignedBB(0, 0, 0, 1, 2.4, 1), + new AxisAlignedBB(0, 0, 0, 1, 2.6, 1), + new AxisAlignedBB(0, 0, 0, 1, 2.8, 1), + new AxisAlignedBB(0, 0, 0, 1, 3, 1) + }; + + public BlockAlfalfa(String domain, String name) { + setRegistryName(domain, name); + setTranslationKey(name); + + setDefaultState(getDefaultState().withProperty(HALF, Half.BOTTOM)); + } + + @Override + public EnumOffsetType getOffsetType() { + return EnumOffsetType.XZ; + } + + @Override + protected PropertyInteger getAgeProperty() { + return AGE; + } + + @Override + public int getMaxAge() { + return 5; + } + + @Override + protected Item getSeed() { + return UItems.alfalfa_seeds; + } + + @Override + protected Item getCrop() { + return UItems.alfalfa_seeds; + } + + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + checkAndDropBlock(world, pos, state); + if (rand.nextInt(10) != 0) { + + if (world.isAreaLoaded(pos, 1) && world.getLightFromNeighbors(pos.up()) >= 9) { + if (canGrow(world, pos, state, false)) { + float f = getGrowthChance(this, world, pos); + + if(ForgeHooks.onCropsGrowPre(world, pos, state, rand.nextInt((int)(25 / f) + 1) == 0)) { + growUpwards(world, pos, state, 1); + ForgeHooks.onCropsGrowPost(world, pos, state, world.getBlockState(pos)); + } + } + } + } + } + + protected void growUpwards(World world, BlockPos pos, IBlockState state, int increase) { + boolean hasDown = world.getBlockState(pos.down()).getBlock() == this; + boolean hasTrunk = world.getBlockState(pos.down(2)).getBlock() == this; + boolean hasRoot = world.getBlockState(pos.down(3)).getBlock() == this; + + if (state.getBlock().isAir(state, world, pos)) { + if (!(hasDown && hasTrunk && hasRoot)) { + world.setBlockState(pos, withAge(increase).withProperty(HALF, Half.TOP)); + } + return; + } + + int age = getAge(state) + increase; + int max = getMaxAge(); + + if (age > max) { + growUpwards(world, pos.up(), world.getBlockState(pos.up()), age - max); + age = max; + } + + + boolean hasUp = world.getBlockState(pos.up()).getBlock() == this; + + if (hasDown && hasUp) { + world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.MIDDLE)); + } else if (hasUp) { + world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.BOTTOM)); + } else { + world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.TOP)); + } + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + if (state.getValue(HALF) != Half.BOTTOM) { + return Items.AIR; + } + + return super.getItemDropped(state, rand, fortune); + } + + @Override + public boolean canBlockStay(World world, BlockPos pos, IBlockState state) { + return getHalf(state) != Half.BOTTOM || super.canBlockStay(world, pos, state); + } + + @Override + public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) { + breakConnectedBlocks(worldIn, pos, player); + } + + protected void breakConnectedBlocks(World worldIn, BlockPos pos, EntityPlayer player) { + IBlockState state = worldIn.getBlockState(pos); + + if (state.getBlock() != this) { + return; + } + + if (player.capabilities.isCreativeMode) { + worldIn.setBlockToAir(pos); + } else { + if (worldIn.isRemote) { + worldIn.setBlockToAir(pos); + } else { + worldIn.destroyBlock(pos, true); + } + } + + Half half = getHalf(state); + + if (half.checkDown()) { + breakConnectedBlocks(worldIn, pos.down(), player); + } + if (half.checkUp()) { + breakConnectedBlocks(worldIn, pos.up(), player); + } + } + + @Override + protected int getBonemealAgeIncrease(World world) { + return super.getBonemealAgeIncrease(world) / 2; + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, HALF, AGE); + } + + @Override + public boolean canCollideCheck(IBlockState state, boolean hitIfLiquid) { + return getHalf(state) != Half.MIDDLE; + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return BOUNDS[Math.min(BOUNDS.length - 1, getFullAge(source, pos))]; + } + + @Override + public boolean canGrow(World world, BlockPos pos, IBlockState state, boolean isClient) { + + + Half half = getHalf(state); + + if (half == Half.MIDDLE || (half == Half.TOP && world.getBlockState(pos.down()).getBlock() == this)) { + return false; + } + + IBlockState above = world.getBlockState(pos.up(1)); + IBlockState higher = world.getBlockState(pos.up(2)); + + boolean iCanGrow = !isMaxAge(state); + boolean aboveCanGrow = above.getBlock() != this || !isMaxAge(above); + boolean higherCanGrow = higher.getBlock() != this || !isMaxAge(higher); + + return iCanGrow || aboveCanGrow || higherCanGrow; + } + + @Override + public void grow(World world, BlockPos pos, IBlockState state) { + growUpwards(world, pos, state, getBonemealAgeIncrease(world)); + } + + protected BlockPos getTip(World world, BlockPos pos) { + BlockPos above = pos.up(); + IBlockState state = world.getBlockState(above); + + if (state.getBlock() == this) { + return getTip(world, above); + } + + return pos; + } + + protected int getFullAge(IBlockAccess world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + + int age = 0; + + if (state.getBlock() == this) { + age += state.getValue(getAgeProperty()); + + age += getFullAge(world, pos.up()); + } + + return age; + } + + protected Half getHalf(IBlockState state) { + return (Half)state.getValue(HALF); + } + + public static enum Half implements IStringSerializable { + TOP, + MIDDLE, + BOTTOM; + + boolean checkUp() { + return this != TOP; + } + + boolean checkDown() { + return this != BOTTOM; + } + + public String toString() { + return getName(); + } + + public String getName() { + return this == TOP ? "top" : this == MIDDLE ? "middle" : "bottom"; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/player/PlayerGravityDelegate.java b/src/main/java/com/minelittlepony/unicopia/player/PlayerGravityDelegate.java index e69aa40a..c441a56c 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/PlayerGravityDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/player/PlayerGravityDelegate.java @@ -7,6 +7,7 @@ import net.minecraft.block.Block; import net.minecraft.block.SoundType; 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.init.MobEffects; import net.minecraft.init.SoundEvents; @@ -63,7 +64,7 @@ class PlayerGravityDelegate implements IUpdatable, IGravity, InbtS float forward = 0.00015F * flightExperience; entity.motionX += - forward * MathHelper.sin(entity.rotationYaw * 0.017453292F); - entity.motionY -= 0.05F - ((entity.motionX * entity.motionX) + (entity.motionZ + entity.motionZ)) / 100; + entity.motionY -= 0.05F - getHorizontalMotion(entity) / 100; entity.motionZ += forward * MathHelper.cos(entity.rotationYaw * 0.017453292F); if (ticksInAir > 0 && ticksInAir % 12 == 0) { @@ -111,6 +112,11 @@ class PlayerGravityDelegate implements IUpdatable, IGravity, InbtS } } + protected double getHorizontalMotion(Entity e) { + return (e.motionX * e.motionX) + + (e.motionZ * e.motionZ); + } + protected SoundEvent getFallSound(int distance) { return distance > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL; } diff --git a/src/main/resources/assets/unicopia/blockstates/alfalfa.json b/src/main/resources/assets/unicopia/blockstates/alfalfa.json new file mode 100644 index 00000000..d9cda7b3 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/alfalfa.json @@ -0,0 +1,18 @@ +{ + "variants": { + "age=0,half=top": { "model": "unicopia:alfalfa/stage0" }, + "age=1,half=top": { "model": "unicopia:alfalfa/stage1" }, + "age=2,half=top": { "model": "unicopia:alfalfa/stage2" }, + "age=3,half=top": { "model": "unicopia:alfalfa/stage3" }, + "age=4,half=top": { "model": "unicopia:alfalfa/stage4" }, + "age=5,half=top": { "model": "unicopia:alfalfa/stage5" }, + "age=0,half=bottom": { "model": "unicopia:alfalfa/stage0" }, + "age=1,half=bottom": { "model": "unicopia:alfalfa/stage1" }, + "age=2,half=bottom": { "model": "unicopia:alfalfa/stage2" }, + "age=3,half=bottom": { "model": "unicopia:alfalfa/stage3" }, + "age=4,half=bottom": { "model": "unicopia:alfalfa/stage4" }, + "age=5,half=bottom": { "model": "unicopia:alfalfa/stage5" }, + "age=5,half=bottom": { "model": "unicopia:alfalfa/shaft" }, + "age=5,half=middle": { "model": "unicopia:alfalfa/shaft" } + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/shaft.json b/src/main/resources/assets/unicopia/models/block/alfalfa/shaft.json new file mode 100644 index 00000000..fff5865a --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/shaft.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/shaft" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage0.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage0.json new file mode 100644 index 00000000..6b5849d9 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage0.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_0" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage1.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage1.json new file mode 100644 index 00000000..bf8b82df --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage1.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_1" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage2.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage2.json new file mode 100644 index 00000000..4b66d294 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage2.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_2" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage3.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage3.json new file mode 100644 index 00000000..2998e970 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage3.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_3" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage4.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage4.json new file mode 100644 index 00000000..a53a783c --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage4.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_4" + } +} diff --git a/src/main/resources/assets/unicopia/models/block/alfalfa/stage5.json b/src/main/resources/assets/unicopia/models/block/alfalfa/stage5.json new file mode 100644 index 00000000..f3966197 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/alfalfa/stage5.json @@ -0,0 +1,6 @@ +{ + "parent": "block/crop", + "textures": { + "crop": "unicopia:blocks/alfalfa/stage_5" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/alfalfa_seeds.json b/src/main/resources/assets/unicopia/models/item/alfalfa_seeds.json new file mode 100644 index 00000000..dee78568 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/alfalfa_seeds.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:items/alfalfa_seeds" + } +} diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/shaft.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/shaft.png new file mode 100644 index 00000000..cf9c0633 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/shaft.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_0.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_0.png new file mode 100644 index 00000000..a0511f88 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_0.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_1.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_1.png new file mode 100644 index 00000000..332d9409 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_1.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_2.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_2.png new file mode 100644 index 00000000..a74bec8c Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_2.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_3.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_3.png new file mode 100644 index 00000000..9cb95205 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_3.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_4.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_4.png new file mode 100644 index 00000000..97532326 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_4.png differ diff --git a/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_5.png b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_5.png new file mode 100644 index 00000000..b349821d Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/blocks/alfalfa/stage_5.png differ diff --git a/src/main/resources/assets/unicopia/textures/items/alfalfa_seeds.png b/src/main/resources/assets/unicopia/textures/items/alfalfa_seeds.png new file mode 100644 index 00000000..46821609 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/items/alfalfa_seeds.png differ