Fixed some issues with alpfalfa, added cloud farmland, added tomatos

This commit is contained in:
Sollace 2019-01-06 23:31:34 +02:00
parent 842770d940
commit c996701734
28 changed files with 802 additions and 50 deletions

View file

@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.block.BlockCloudAnvil;
import com.minelittlepony.unicopia.block.BlockCloudSlab;
import com.minelittlepony.unicopia.block.BlockCloudStairs;
import com.minelittlepony.unicopia.block.BlockCloudDoor;
import com.minelittlepony.unicopia.block.BlockCloudFarm;
import net.minecraft.block.Block;
import net.minecraftforge.registries.IForgeRegistry;
@ -13,9 +14,9 @@ import net.minecraftforge.registries.IForgeRegistry;
public class UBlocks {
public static final BlockCloud cloud = new BlockCloud(UMaterials.cloud, Unicopia.MODID, "cloud_block");
public static final BlockCloudStairs stairsCloud = new BlockCloudStairs(UBlocks.cloud.getDefaultState(), Unicopia.MODID, "cloud_stairs");
public static final BlockCloudStairs cloud_stairs = new BlockCloudStairs(UBlocks.cloud.getDefaultState(), Unicopia.MODID, "cloud_stairs");
public static final BlockCloudSlab cloud_double_slab = new BlockCloudSlab(true, UMaterials.cloud, Unicopia.MODID, "cloud_double_slab");
public static final BlockCloudSlab double_cloud_slab = new BlockCloudSlab(true, UMaterials.cloud, Unicopia.MODID, "cloud_double_slab");
public static final BlockCloudSlab cloud_slab = new BlockCloudSlab(false, UMaterials.cloud, Unicopia.MODID, "cloud_slab");
public static final BlockCloudDoor mist_door = new BlockCloudDoor(UMaterials.cloud, Unicopia.MODID, "mist_door");
@ -24,8 +25,10 @@ public class UBlocks {
public static final BlockAlfalfa alfalfa = new BlockAlfalfa(Unicopia.MODID, "alfalfa");
public static final BlockCloudFarm cloud_farmland = new BlockCloudFarm(Unicopia.MODID, "cloud_farmland");
static void registerBlocks(IForgeRegistry<Block> registry) {
registry.registerAll(cloud, stairsCloud, cloud_double_slab, cloud_slab, mist_door, anvil,
registry.registerAll(cloud, cloud_stairs, double_cloud_slab, cloud_slab, mist_door, anvil, cloud_farmland,
alfalfa);
}
}

View file

@ -4,15 +4,18 @@ import com.minelittlepony.unicopia.entity.EntityCloud;
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.entity.EntityProjectile;
import com.minelittlepony.unicopia.entity.EntityWildCloud;
import com.minelittlepony.unicopia.render.RenderCloud;
import com.minelittlepony.unicopia.render.RenderGem;
import com.minelittlepony.unicopia.render.RenderProjectile;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList.EntityEggInfo;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
import net.minecraftforge.registries.IForgeRegistry;
public class UEntities {
@ -20,25 +23,33 @@ public class UEntities {
private static final int BRUSHES_CHARTREUSE = 0x7FFF00;
static void init(IForgeRegistry<EntityEntry> registry) {
addEntity(registry, EntityCloud.class, "cloud", true, BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE);
addEntity(registry, EntityWildCloud.class, "wild_cloud", false, 0, 0);
addEntity(registry, EntityRacingCloud.class, "racing_cloud", false, 0, 0);
addEntity(registry, EntityConstructionCloud.class, "construction_cloud", false, 0, 0);
addEntity(registry, EntitySpell.class, "magic_spell", false, 0, 0);
}
static <T extends Entity> void addEntity(IForgeRegistry<EntityEntry> registry, Class<T> type, String name, boolean egg, int a, int b) {
EntityEntry entry = new EntityEntry(type, name).setRegistryName(Unicopia.MODID, name);
if (egg) {
entry.setEgg(new EntityEggInfo(new ResourceLocation("unicopia", "cloud"), a, a));
}
registry.register(entry);
registry.registerAll(
new Entry(EntityCloud.class, "cloud").withEgg(BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE),
new Entry(EntityWildCloud.class, "wild_cloud"),
new Entry(EntityRacingCloud.class, "racing_cloud"),
new Entry(EntityConstructionCloud.class, "construction_cloud"),
new Entry(EntitySpell.class, "magic_spell"),
EntityEntryBuilder.<EntityProjectile>create().entity(EntityProjectile.class).name("thrown_item").id(new ResourceLocation(Unicopia.MODID, "thrown_item"), 0).tracker(10, 5, true).build()
);
}
static void preInit() {
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, manager -> new RenderCloud(manager));
RenderingRegistry.registerEntityRenderingHandler(EntitySpell.class, manager -> new RenderGem(manager));
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, RenderCloud::new);
RenderingRegistry.registerEntityRenderingHandler(EntitySpell.class, RenderGem::new);
RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new);
}
static class Entry extends EntityEntry {
public Entry(Class<? extends Entity> cls, String name) {
super(cls, name);
setRegistryName(Unicopia.MODID, name);
}
Entry withEgg(int a, int b) {
setEgg(new EntityEggInfo(getRegistryName(), a, b));
return this;
}
}
}

View file

@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.item.ItemCloud;
import com.minelittlepony.unicopia.item.ItemCurse;
import com.minelittlepony.unicopia.item.ItemOfHolding;
import com.minelittlepony.unicopia.item.ItemSpell;
import com.minelittlepony.unicopia.item.ItemTomato;
import com.minelittlepony.unicopia.item.UItemBlock;
import com.minelittlepony.unicopia.item.UItemMultiTexture;
import com.minelittlepony.unicopia.item.UItemSlab;
@ -57,7 +58,7 @@ public class UItems {
}, INTERACT_WITH_CLOUDS)
.setRegistryName(Unicopia.MODID, "cloud_block");
public static final Item cloud_stairs = new UItemBlock(UBlocks.stairsCloud, INTERACT_WITH_CLOUDS)
public static final Item cloud_stairs = new UItemBlock(UBlocks.cloud_stairs, INTERACT_WITH_CLOUDS)
.setTranslationKey("cloud_stairs")
.setRegistryName(Unicopia.MODID, "cloud_stairs");
@ -70,7 +71,7 @@ public class UItems {
.setTranslationKey("mist_door")
.setRegistryName(Unicopia.MODID, "mist_door");
public static final Item cloud_slab = new UItemSlab(UBlocks.cloud_slab, UBlocks.cloud_slab, UBlocks.cloud_double_slab, INTERACT_WITH_CLOUDS)
public static final Item cloud_slab = new UItemSlab(UBlocks.cloud_slab, UBlocks.cloud_slab, UBlocks.double_cloud_slab, INTERACT_WITH_CLOUDS)
.setTranslationKey("cloud_slab")
.setRegistryName(Unicopia.MODID, "cloud_slab");
@ -91,6 +92,9 @@ public class UItems {
.setTranslationKey("cereal")
.setRegistryName(Unicopia.MODID, "cereal");
public static final ItemTomato tomato = new ItemTomato(Unicopia.MODID, "tomato", 4, 34);
public static final ItemTomato cloudsdale_tomato = new ItemTomato(Unicopia.MODID, "cloudsdale_tomato", 16, 4);
static void registerItems(IForgeRegistry<Item> registry) {
RegistryLockSpinner.unlock(Item.REGISTRY);
@ -98,12 +102,10 @@ public class UItems {
RegistryLockSpinner.lock(Item.REGISTRY);
registry.registerAll(cloud_spawner, dew_drop, cloud_matter, cloud_block,
cloud_stairs, cloud_slab, mist_door, anvil,
bag_of_holding, spell, curse,
alfalfa_seeds, alfalfa_leaves, cereal);
alfalfa_seeds, alfalfa_leaves, cereal, tomato);
if (UClient.isClientSide()) {
registerAllVariants(apple, apple.getVariants());
@ -121,6 +123,8 @@ public class UItems {
registerAllVariants(alfalfa_seeds, "alfalfa_seeds");
registerAllVariants(alfalfa_leaves, "alfalfa_leaves");
registerAllVariants(cereal, "cereal");
registerAllVariants(tomato, "tomato", "rotten_tomato");
registerAllVariants(cloudsdale_tomato, "cloudsdale_tomato", "rotten_cloudsdale_tomato");
}
registerFuels();

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
@ -10,6 +11,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.client.event.FOVUpdateEvent;
@ -20,6 +23,7 @@ import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.player.PlayerDropsEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.UseHoeEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -27,6 +31,7 @@ import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.Event.Result;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
@ -38,6 +43,7 @@ import com.minelittlepony.jumpingcastle.api.IChannel;
import com.minelittlepony.jumpingcastle.api.JumpingCastle;
import com.minelittlepony.jumpingcastle.api.Target;
import com.minelittlepony.unicopia.advancements.UAdvancements;
import com.minelittlepony.unicopia.block.ITillable;
import com.minelittlepony.unicopia.client.particle.EntityMagicFX;
import com.minelittlepony.unicopia.client.particle.EntityRaindropFX;
import com.minelittlepony.unicopia.client.particle.Particles;
@ -193,6 +199,25 @@ public class Unicopia {
}
}
@SubscribeEvent
public static void onBlockTilled(UseHoeEvent event) {
BlockPos pos = event.getPos();
World world = event.getWorld();
IBlockState state = world.getBlockState(pos);
if (state.getBlock() instanceof ITillable) {
ITillable farm = ((ITillable)state.getBlock());
if (farm.canBeTilled(event.getCurrent(), event.getEntityPlayer(), world, state, pos)) {
world.setBlockState(pos, farm.getFarmlandState(event.getCurrent(), event.getEntityPlayer(), world, state, pos));
event.setResult(Result.ALLOW);
}
}
}
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.phase == Phase.END) {

View file

@ -19,6 +19,7 @@ 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.EnumPlantType;
import net.minecraftforge.common.ForgeHooks;
public class BlockAlfalfa extends BlockCrops {
@ -116,19 +117,20 @@ public class BlockAlfalfa extends BlockCrops {
int max = getMaxAge();
if (age > max) {
growUpwards(world, pos.up(), world.getBlockState(pos.up()), age - max);
if (!(hasDown && hasTrunk)) {
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));
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.MIDDLE));
} else if (hasUp) {
world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.BOTTOM));
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.BOTTOM));
} else {
world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.TOP));
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.TOP));
}
}
@ -269,6 +271,11 @@ public class BlockAlfalfa extends BlockCrops {
return (Half)state.getValue(HALF);
}
@Override
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) {
return EnumPlantType.Crop;
}
public static enum Half implements IStringSerializable {
TOP,
MIDDLE,

View file

@ -5,6 +5,8 @@ import java.util.List;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.CloudType;
import com.minelittlepony.unicopia.UBlocks;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
@ -25,7 +27,7 @@ import net.minecraft.util.NonNullList;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockCloud extends Block implements ICloudBlock {
public class BlockCloud extends Block implements ICloudBlock, ITillable {
public static final PropertyEnum<CloudType> VARIANT = PropertyEnum.create("variant", CloudType.class);
@ -139,9 +141,9 @@ public class BlockCloud extends Block implements ICloudBlock {
@Override
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) {
if (!CloudType.NORMAL.canInteract(player)) {
return -1;
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
}
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
return -1;
}
@Override
@ -176,4 +178,15 @@ public class BlockCloud extends Block implements ICloudBlock {
return (CloudType)blockState.getValue(VARIANT);
}
@Override
public boolean canBeTilled(ItemStack hoe, EntityPlayer player, World world, IBlockState state, BlockPos pos) {
return PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds()
&& ITillable.super.canBeTilled(hoe, player, world, state, pos);
}
@Override
public IBlockState getFarmlandState(ItemStack hoe, EntityPlayer player, World world, IBlockState state, BlockPos pos) {
return UBlocks.cloud_farmland.getDefaultState();
}
}

View file

@ -0,0 +1,125 @@
package com.minelittlepony.unicopia.block;
import java.util.List;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.CloudType;
import com.minelittlepony.unicopia.UBlocks;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockCloudFarm extends UFarmland implements ICloudBlock {
public BlockCloudFarm(String domain, String name) {
super(domain, name);
}
@Override
public boolean isTranslucent(IBlockState state) {
return true;
}
@Override
public boolean isAir(IBlockState state, IBlockAccess world, BlockPos pos) {
return allowsFallingBlockToPass(state, world, pos);
}
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.TRANSLUCENT;
}
@Override
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
IBlockState beside = world.getBlockState(pos.offset(face));
if (beside.getBlock() instanceof ICloudBlock) {
ICloudBlock cloud = ((ICloudBlock)beside.getBlock());
if ((face == EnumFacing.DOWN || face == EnumFacing.UP || cloud == this)) {
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) {
return true;
}
}
}
return super.doesSideBlockRendering(state, world, pos, face);
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entityIn, float fallDistance) {
if (entityIn.isSneaking()) {
super.onFallenUpon(world, pos, entityIn, fallDistance);
} else {
entityIn.fall(fallDistance, 0);
}
}
@Override
public void onLanded(World worldIn, Entity entity) {
if (entity.isSneaking()) {
super.onLanded(worldIn, entity);
} else if (entity.motionY < 0) {
if (Math.abs(entity.motionY) >= 0.25) {
entity.motionY = -entity.motionY * 1.2;
} else {
entity.motionY = 0;
}
}
}
@Override
public void onEntityCollision(World w, BlockPos pos, IBlockState state, Entity entity) {
if (getCanInteract(state, entity)) {
if (!entity.isSneaking() && Math.abs(entity.motionY) >= 0.25) {
entity.motionY += 0.0155 * (entity.fallDistance < 1 ? 1 : entity.fallDistance);
} else {
entity.motionY = 0;
}
super.onEntityCollision(w, pos, state, entity);
}
}
@Override
public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) {
return getCanInteract(state, entity) && super.canEntityDestroy(state, world, pos, entity);
}
@Deprecated
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entity, boolean p_185477_7_) {
if (getCanInteract(state, entity)) {
super.addCollisionBoxToList(state, worldIn, pos, entityBox, collidingBoxes, entity, p_185477_7_);
}
}
@Deprecated
@Override
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) {
if (CloudType.NORMAL.canInteract(player)) {
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
}
return -1;
}
@Override
public CloudType getCloudMaterialType(IBlockState blockState) {
return CloudType.NORMAL;
}
@Override
protected IBlockState getDirtState(World world, BlockPos pos, IBlockState state) {
return UBlocks.cloud.getDefaultState();
}
}

View file

@ -0,0 +1,24 @@
package com.minelittlepony.unicopia.block;
import javax.annotation.Nonnull;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* Blocks that can be turned into farmland when tilled.
*/
public interface ITillable {
/**
* Gets the farmland/tilled state for this block when attacked by a hoe.
*/
@Nonnull
IBlockState getFarmlandState(ItemStack hoe, EntityPlayer player, World world, IBlockState state, BlockPos pos);
default boolean canBeTilled(ItemStack hoe, EntityPlayer player, World world, IBlockState state, BlockPos pos) {
return world.isAirBlock(pos.up());
}
}

View file

@ -0,0 +1,127 @@
package com.minelittlepony.unicopia.block;
import java.util.Random;
import com.minelittlepony.util.PosHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFarmland;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
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.EnumPlantType;
import net.minecraftforge.common.IPlantable;
public abstract class UFarmland extends BlockFarmland {
public UFarmland(String domain, String name) {
setTranslationKey(name);
setRegistryName(domain, name);
}
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) {
int i = state.getValue(MOISTURE);
if (!hasWater(world, pos) && !world.isRainingAt(pos.up())) {
if (i > 0) {
world.setBlockState(pos, state.withProperty(MOISTURE, i - 1), 2);
} else if (!hasCrops(world, pos)) {
turnToDirt(world, pos, state);
}
} else if (i < 7) {
world.setBlockState(pos, state.withProperty(MOISTURE, 7), 2);
}
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance) {
if (shouldTrample(world, pos, entity, fallDistance)) {
turnToDirt(world, pos, world.getBlockState(pos));
}
entity.fall(fallDistance, 1);
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
@Override
public void onBlockAdded(World world, BlockPos pos, IBlockState state) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
public boolean hasCrops(World worldIn, BlockPos pos) {
Block block = worldIn.getBlockState(pos.up()).getBlock();
return block instanceof IPlantable
&& canSustainPlant(worldIn.getBlockState(pos), worldIn, pos, EnumFacing.UP, (IPlantable)block);
}
public boolean hasWater(World world, BlockPos pos) {
return PosHelper.inRegion(pos.add(-4, 0, -4), pos.add(4, 1, 4)).anyMatch(p -> {
return world.getBlockState(p).getMaterial() == Material.WATER;
});
}
@Override
public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, IPlantable plantable) {
return super.canSustainPlant(state, world, pos, direction, plantable)
|| plantable.getPlantType(world, pos.offset(direction)) == EnumPlantType.Crop;
}
/**
* Determines if this farmland should be trampled when an entity walks on it.
*/
public boolean shouldTrample(World world, BlockPos pos, Entity entity, float fallDistance) {
return !world.isRemote && entity.canTrample(world, this, pos, fallDistance);
}
/**
* Determines if this farmland meets all the conditions for turning into dirt.
*/
public boolean shouldTurnToDirt(World world, BlockPos pos, IBlockState state) {
return world.getBlockState(pos.up()).getMaterial().isSolid();
}
/**
* Turns this farmland into dirt or its dirt equivalent.
*/
public void turnToDirt(World world, BlockPos pos, IBlockState state) {
world.setBlockState(pos, getDirtState(world, pos, state));
AxisAlignedBB bounds = getUpdateCollissionBounds(world, pos, state);
if (bounds != null) {
// Update entity positions so they don't fall through the block
for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bounds)) {
double offset = Math.min(bounds.maxY - bounds.minY, bounds.maxY - entity.getEntityBoundingBox().minY);
entity.setPositionAndUpdate(entity.posX, entity.posY + offset + 0.001D, entity.posZ);
}
}
}
protected AxisAlignedBB getUpdateCollissionBounds(World world, BlockPos pos, IBlockState state) {
return field_194405_c.offset(pos);
}
/**
* Gets the state used to represent this block as a piece of dirt.
*/
protected IBlockState getDirtState(World world, BlockPos pos, IBlockState state) {
return Blocks.DIRT.getDefaultState();
}
}

View file

@ -0,0 +1,121 @@
package com.minelittlepony.unicopia.entity;
import com.minelittlepony.unicopia.item.ITossable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.projectile.EntitySnowball;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class EntityProjectile extends EntitySnowball {
private static final DataParameter<ItemStack> ITEM = EntityDataManager
.createKey(EntityProjectile.class, DataSerializers.ITEM_STACK);
private static final DataParameter<Float> DAMAGE = EntityDataManager
.createKey(EntityProjectile.class, DataSerializers.FLOAT);
public EntityProjectile(World world) {
super(world);
}
public EntityProjectile(World world, double x, double y, double z) {
super(world, x, y, z);
}
public EntityProjectile(World world, EntityLivingBase thrower) {
super(world, thrower);
}
@Override
protected void entityInit() {
getDataManager().register(ITEM, ItemStack.EMPTY);
getDataManager().register(DAMAGE, (float)0);
}
public ItemStack getItem() {
ItemStack stack = getDataManager().get(ITEM);
return stack == null ? ItemStack.EMPTY : stack;
}
public void setItem(ItemStack stack) {
getDataManager().set(ITEM, stack);
getDataManager().setDirty(ITEM);
}
public void setThrowDamage(float damage) {
getDataManager().set(DAMAGE, Math.max(0, damage));
}
public float getThrowDamage() {
return getDataManager().get(DAMAGE);
}
@Override
public void readEntityFromNBT(NBTTagCompound compound) {
super.readEntityFromNBT(compound);
ItemStack itemstack = new ItemStack(compound.getCompoundTag("Item"));
if (itemstack.isEmpty()) {
setDead();
} else {
setItem(itemstack);
}
}
@Override
public void handleStatusUpdate(byte id) {
if (id == 3) {
ItemStack stack = getItem();
for (int i = 0; i < 8; i++) {
world.spawnParticle(EnumParticleTypes.ITEM_CRACK, posX, posY, posZ, 0, 0, 0, Item.getIdFromItem(stack.getItem()), stack.getMetadata());
}
}
}
@Override
public void writeEntityToNBT(NBTTagCompound compound) {
super.writeEntityToNBT(compound);
ItemStack itemstack = this.getItem();
if (!itemstack.isEmpty()) {
compound.setTag("Item", itemstack.writeToNBT(new NBTTagCompound()));
}
}
@Override
protected void onImpact(RayTraceResult result) {
if (result.entityHit != this && !(result.entityHit instanceof IProjectile)) {
if (result.typeOfHit == RayTraceResult.Type.BLOCK) {
Item item = getItem().getItem();
if (item instanceof ITossable) {
((ITossable)item).onImpact(world, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
}
}
if (result.entityHit != null) {
result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, getThrower()), getThrowDamage());
}
if (!world.isRemote) {
world.setEntityState(this, (byte)3);
setDead();
}
}
}
}

View file

@ -0,0 +1,105 @@
package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.entity.EntityProjectile;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.state.IBlockState;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBehaviorDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.dispenser.IPosition;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface ITossable {
IBehaviorDispenseItem dispenserBehavior = new ITossable.DispenserBehaviour();
boolean canBeThrown(ItemStack stack);
void onImpact(World world, BlockPos pos, IBlockState state);
default Item setDispenseable() {
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject((Item)(Object)this, dispenserBehavior);
return (Item)(Object)this;
}
default SoundEvent getThrowSound(ItemStack stack) {
return SoundEvents.ENTITY_SNOWBALL_THROW;
}
default int getThrowDamage(ItemStack stack) {
return 0;
}
default void toss(World world, ItemStack itemstack, EntityPlayer player) {
if (!player.capabilities.isCreativeMode) {
itemstack.shrink(1);
}
world.playSound(null, player.posX, player.posY, player.posZ, getThrowSound(itemstack), SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
if (!world.isRemote) {
EntityProjectile projectile = new EntityProjectile(world, player);
projectile.setItem(itemstack);
projectile.setThrowDamage(getThrowDamage(itemstack));
projectile.shoot(player, player.rotationPitch, player.rotationYaw, 0, 1.5F, 1);
world.spawnEntity(projectile);
}
player.addStat(StatList.getObjectUseStats(itemstack.getItem()));
}
default ItemStack toss(World world, IPosition pos, EnumFacing facing, ItemStack stack, float velocity, float inaccuracy) {
EntityProjectile iprojectile = new EntityProjectile(world, pos.getX(), pos.getY(), pos.getZ());
iprojectile.setItem(stack);
iprojectile.setThrowDamage(getThrowDamage(stack));
iprojectile.shoot(facing.getXOffset(), facing.getYOffset() + 0.1F, facing.getZOffset(), velocity, inaccuracy);
world.spawnEntity(iprojectile);
stack.shrink(1);
return stack;
}
class DispenserBehaviour extends BehaviorDefaultDispenseItem {
@Override
public ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
ITossable tossable = (ITossable)stack.getItem();
if (tossable.canBeThrown(stack)) {
return shootStack(source, stack);
}
return super.dispenseStack(source, stack);
}
public ItemStack shootStack(IBlockSource source, ItemStack stack) {
return ((ITossable)stack.getItem()).toss(source.getWorld(),
BlockDispenser.getDispensePosition(source),
(EnumFacing)source.getBlockState().getValue(BlockDispenser.FACING),
stack, getProjectileInaccuracy(), getProjectileVelocity());
}
protected float getProjectileInaccuracy() {
return 6.0F;
}
protected float getProjectileVelocity() {
return 1.1F;
}
}
}

View file

@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.item;
import java.util.Random;
import com.minelittlepony.unicopia.UItems;
import com.minelittlepony.util.MagicalDamageSource;
import com.minelittlepony.util.vector.VecHelper;
@ -63,20 +62,25 @@ public class ItemApple extends ItemFood {
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
RayTraceResult mop = VecHelper.getObjectMouseOver(player, 5, 0);
if (mop != null && mop.typeOfHit == RayTraceResult.Type.ENTITY) {
ItemStack stack = player.getHeldItem(hand);
if (canFeedTo(stack, mop.entityHit)) {
return onFedTo(stack, player, mop.entityHit);
}
}
return super.onItemRightClick(world, player, hand);
}
@Override
protected void onFoodEaten(ItemStack stack, World w, EntityPlayer player) {
super.onFoodEaten(stack, w, player);
if (isZapApple(stack)) {
player.attackEntityFrom(MagicalDamageSource.create("zap"), 120);
w.addWeatherEffect(new EntityLightningBolt(w, player.posX, player.posY, player.posZ, false));
}
}
@ -92,7 +96,11 @@ public class ItemApple extends ItemFood {
public ActionResult<ItemStack> onFedTo(ItemStack stack, EntityPlayer player, Entity e) {
e.onStruckByLightning(new EntityLightningBolt(e.world, e.posX, e.posY, e.posZ, false));
if (!player.capabilities.isCreativeMode) stack.shrink(1);
if (!player.capabilities.isCreativeMode) {
stack.shrink(1);
}
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
}
@ -103,7 +111,9 @@ public class ItemApple extends ItemFood {
public ItemApple setSubTypes(String... types) {
subTypes = types;
variants = new String[subTypes.length * 2];
setTranslationKey(variants[0] = types[0]);
for (int i = 1; i < variants.length; i++) {
variants[i] = variants[0] + (i % subTypes.length != 0 ? "_" + subTypes[i % subTypes.length] : "");
}
@ -123,7 +133,7 @@ public class ItemApple extends ItemFood {
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items) {
if (isInCreativeTab(tab)) {
for (int i = 0; i < subTypes.length; i++) {
items.add(new ItemStack(UItems.apple, 1, i));
items.add(new ItemStack(this, 1, i));
}
}
}
@ -131,23 +141,22 @@ public class ItemApple extends ItemFood {
@Override
public EnumRarity getRarity(ItemStack stack) {
int meta = stack.getMetadata();
if (meta == getZapAppleMetadata()) return EnumRarity.EPIC;
if (meta >= subTypes.length) return EnumRarity.RARE;
if (meta == getZapAppleMetadata()) {
return EnumRarity.EPIC;
}
if (meta >= subTypes.length) {
return EnumRarity.RARE;
}
return EnumRarity.COMMON;
}
/*public String getItemStackDisplayName(ItemStack stack) {
String result = super.getItemStackDisplayName(stack);
if (stack.getMetadata() >= subTypes.length) {
return ChatColor.ITALIC + result;
}
return result;
}*/
@Override
public String getTranslationKey(ItemStack stack) {
int meta = stack.getMetadata() % subTypes.length;
if (meta < 0) meta = 0;
int meta = Math.max(0, stack.getMetadata() % subTypes.length);
return super.getTranslationKey(stack) + (meta > 0 ? "." + subTypes[meta] : "");
}

View file

@ -0,0 +1,91 @@
package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ItemTomato extends ItemFood implements ITossable {
public ItemTomato(String domain, String name, int heal, int sat) {
super(heal, sat, false);
setTranslationKey(name);
setRegistryName(domain, name);
setDispenseable();
}
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items) {
if (isInCreativeTab(tab)) {
items.add(new ItemStack(this, 1, 0));
items.add(new ItemStack(this, 1, 1));
}
}
@Override
public String getTranslationKey(ItemStack stack) {
return super.getTranslationKey(stack) + (canBeThrown(stack) ? ".rotten" : "");
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
ItemStack itemstack = player.getHeldItem(hand);
if (canBeThrown(itemstack) && !player.canEat(false)) {
toss(world, itemstack, player);
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack);
}
return super.onItemRightClick(world, player, hand);
}
public boolean canBeThrown(ItemStack stack) {
return stack.getMetadata() > 0;
}
protected boolean isSickening(ItemStack stack, EntityPlayer player) {
return canBeThrown(stack)
&& !PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canUseEarth();
}
@Override
protected void onFoodEaten(ItemStack stack, World worldIn, EntityPlayer player) {
PotionEffect effect = player.getActivePotionEffect(MobEffects.NAUSEA);
if (isSickening(stack, player)) {
int duration = 7000;
if (effect != null) {
duration += Math.max(0, effect.getDuration());
}
player.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, duration, 4));
} else if (effect != null) {
player.removePotionEffect(MobEffects.NAUSEA);
}
super.onFoodEaten(stack, worldIn, player);
}
@Override
public void onImpact(World world, BlockPos pos, IBlockState state) {
if (!world.isRemote && state.getMaterial() == Material.GLASS) {
world.destroyBlock(pos, true);
}
}
}

View file

@ -60,12 +60,11 @@ class PlayerGravityDelegate implements IUpdatable<EntityPlayer>, IGravity, InbtS
entity.fallDistance = 0;
float exhaustion = (0.2F * ticksInAir++) / 90;
float exhaustion = (0.5F * ticksInAir++) / 70;
if (entity.isSprinting()) {
exhaustion *= 3.11F;
}
exhaustion *= (1 - flightExperience/MAXIMUM_FLIGHT_EXPERIENCE);
entity.addExhaustion(exhaustion);

View file

@ -0,0 +1,21 @@
package com.minelittlepony.unicopia.render;
import com.minelittlepony.unicopia.entity.EntityProjectile;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderSnowball;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
public class RenderProjectile extends RenderSnowball<EntityProjectile> {
public RenderProjectile(RenderManager renderManager) {
super(renderManager, Items.POTIONITEM, Minecraft.getMinecraft().getRenderItem());
}
@Override
public ItemStack getStackToRender(EntityProjectile entity) {
return entity.getItem();
}
}

View file

@ -2,9 +2,13 @@ package com.minelittlepony.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import com.google.common.collect.Streams;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
public class PosHelper {
@ -22,4 +26,11 @@ public class PosHelper {
}
return false;
}
/**
* Creates a stream of mutable block positions ranging from the beginning position to end.
*/
public static Stream<MutableBlockPos> inRegion(BlockPos from, BlockPos to) {
return Streams.stream(BlockPos.getAllInBoxMutable(from, to));
}
}

View file

@ -0,0 +1,12 @@
{
"variants": {
"moisture=0": { "model": "unicopia:farmland/dry" },
"moisture=1": { "model": "unicopia:farmland/dry" },
"moisture=2": { "model": "unicopia:farmland/dry" },
"moisture=3": { "model": "unicopia:farmland/dry" },
"moisture=4": { "model": "unicopia:farmland/dry" },
"moisture=5": { "model": "unicopia:farmland/dry" },
"moisture=6": { "model": "unicopia:farmland/dry" },
"moisture=7": { "model": "unicopia:farmland/wet" }
}
}

View file

@ -45,6 +45,10 @@ item.apple.rotten.name=Rotten Apple
item.apple.zap.name=Zap Apple
item.apple.zap_cooked.name=Cooked Zap Apple
item.tomato.name=Tomato
item.tomato.rotten.name=Rotten Tomato
item.tomato.cloud.name=Cloudsdale Tomato
item.alfalfa_leaves.name=Alfalfa
item.alfalfa_seeds.name=Grain

View file

@ -0,0 +1,8 @@
{
"parent": "block/farmland",
"textures": {
"particle": "unicopia:blocks/cloud_normal",
"dirt": "unicopia:blocks/cloud_normal",
"top": "unicopia:blocks/cloud_farmland_dry"
}
}

View file

@ -0,0 +1,8 @@
{
"parent": "block/farmland",
"textures": {
"particle": "unicopia:blocks/cloud_normal",
"dirt": "unicopia:blocks/cloud_normal",
"top": "unicopia:blocks/cloud_farmland_wet"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:items/tomato"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:items/rotten_tomato"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:items/rotten_tomato"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:items/tomato"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB