mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fixed some issues with alpfalfa, added cloud farmland, added tomatos
This commit is contained in:
parent
842770d940
commit
c996701734
28 changed files with 802 additions and 50 deletions
|
@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.block.BlockCloudAnvil;
|
||||||
import com.minelittlepony.unicopia.block.BlockCloudSlab;
|
import com.minelittlepony.unicopia.block.BlockCloudSlab;
|
||||||
import com.minelittlepony.unicopia.block.BlockCloudStairs;
|
import com.minelittlepony.unicopia.block.BlockCloudStairs;
|
||||||
import com.minelittlepony.unicopia.block.BlockCloudDoor;
|
import com.minelittlepony.unicopia.block.BlockCloudDoor;
|
||||||
|
import com.minelittlepony.unicopia.block.BlockCloudFarm;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
@ -13,9 +14,9 @@ import net.minecraftforge.registries.IForgeRegistry;
|
||||||
public class UBlocks {
|
public class UBlocks {
|
||||||
public static final BlockCloud cloud = new BlockCloud(UMaterials.cloud, Unicopia.MODID, "cloud_block");
|
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 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");
|
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 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) {
|
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);
|
alfalfa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,18 @@ import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||||
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
||||||
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
|
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
|
||||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityProjectile;
|
||||||
import com.minelittlepony.unicopia.entity.EntityWildCloud;
|
import com.minelittlepony.unicopia.entity.EntityWildCloud;
|
||||||
import com.minelittlepony.unicopia.render.RenderCloud;
|
import com.minelittlepony.unicopia.render.RenderCloud;
|
||||||
import com.minelittlepony.unicopia.render.RenderGem;
|
import com.minelittlepony.unicopia.render.RenderGem;
|
||||||
|
import com.minelittlepony.unicopia.render.RenderProjectile;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityList.EntityEggInfo;
|
import net.minecraft.entity.EntityList.EntityEggInfo;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||||
import net.minecraftforge.fml.common.registry.EntityEntry;
|
import net.minecraftforge.fml.common.registry.EntityEntry;
|
||||||
|
import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
|
||||||
public class UEntities {
|
public class UEntities {
|
||||||
|
@ -20,25 +23,33 @@ public class UEntities {
|
||||||
private static final int BRUSHES_CHARTREUSE = 0x7FFF00;
|
private static final int BRUSHES_CHARTREUSE = 0x7FFF00;
|
||||||
|
|
||||||
static void init(IForgeRegistry<EntityEntry> registry) {
|
static void init(IForgeRegistry<EntityEntry> registry) {
|
||||||
addEntity(registry, EntityCloud.class, "cloud", true, BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE);
|
registry.registerAll(
|
||||||
addEntity(registry, EntityWildCloud.class, "wild_cloud", false, 0, 0);
|
new Entry(EntityCloud.class, "cloud").withEgg(BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE),
|
||||||
addEntity(registry, EntityRacingCloud.class, "racing_cloud", false, 0, 0);
|
new Entry(EntityWildCloud.class, "wild_cloud"),
|
||||||
addEntity(registry, EntityConstructionCloud.class, "construction_cloud", false, 0, 0);
|
new Entry(EntityRacingCloud.class, "racing_cloud"),
|
||||||
addEntity(registry, EntitySpell.class, "magic_spell", false, 0, 0);
|
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 <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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void preInit() {
|
static void preInit() {
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, manager -> new RenderCloud(manager));
|
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, RenderCloud::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpell.class, manager -> new RenderGem(manager));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.item.ItemCloud;
|
||||||
import com.minelittlepony.unicopia.item.ItemCurse;
|
import com.minelittlepony.unicopia.item.ItemCurse;
|
||||||
import com.minelittlepony.unicopia.item.ItemOfHolding;
|
import com.minelittlepony.unicopia.item.ItemOfHolding;
|
||||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||||
|
import com.minelittlepony.unicopia.item.ItemTomato;
|
||||||
import com.minelittlepony.unicopia.item.UItemBlock;
|
import com.minelittlepony.unicopia.item.UItemBlock;
|
||||||
import com.minelittlepony.unicopia.item.UItemMultiTexture;
|
import com.minelittlepony.unicopia.item.UItemMultiTexture;
|
||||||
import com.minelittlepony.unicopia.item.UItemSlab;
|
import com.minelittlepony.unicopia.item.UItemSlab;
|
||||||
|
@ -57,7 +58,7 @@ public class UItems {
|
||||||
}, INTERACT_WITH_CLOUDS)
|
}, INTERACT_WITH_CLOUDS)
|
||||||
.setRegistryName(Unicopia.MODID, "cloud_block");
|
.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")
|
.setTranslationKey("cloud_stairs")
|
||||||
.setRegistryName(Unicopia.MODID, "cloud_stairs");
|
.setRegistryName(Unicopia.MODID, "cloud_stairs");
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ public class UItems {
|
||||||
.setTranslationKey("mist_door")
|
.setTranslationKey("mist_door")
|
||||||
.setRegistryName(Unicopia.MODID, "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")
|
.setTranslationKey("cloud_slab")
|
||||||
.setRegistryName(Unicopia.MODID, "cloud_slab");
|
.setRegistryName(Unicopia.MODID, "cloud_slab");
|
||||||
|
|
||||||
|
@ -91,6 +92,9 @@ public class UItems {
|
||||||
.setTranslationKey("cereal")
|
.setTranslationKey("cereal")
|
||||||
.setRegistryName(Unicopia.MODID, "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) {
|
static void registerItems(IForgeRegistry<Item> registry) {
|
||||||
RegistryLockSpinner.unlock(Item.REGISTRY);
|
RegistryLockSpinner.unlock(Item.REGISTRY);
|
||||||
|
|
||||||
|
@ -98,12 +102,10 @@ public class UItems {
|
||||||
|
|
||||||
RegistryLockSpinner.lock(Item.REGISTRY);
|
RegistryLockSpinner.lock(Item.REGISTRY);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
registry.registerAll(cloud_spawner, dew_drop, cloud_matter, cloud_block,
|
registry.registerAll(cloud_spawner, dew_drop, cloud_matter, cloud_block,
|
||||||
cloud_stairs, cloud_slab, mist_door, anvil,
|
cloud_stairs, cloud_slab, mist_door, anvil,
|
||||||
bag_of_holding, spell, curse,
|
bag_of_holding, spell, curse,
|
||||||
alfalfa_seeds, alfalfa_leaves, cereal);
|
alfalfa_seeds, alfalfa_leaves, cereal, tomato);
|
||||||
|
|
||||||
if (UClient.isClientSide()) {
|
if (UClient.isClientSide()) {
|
||||||
registerAllVariants(apple, apple.getVariants());
|
registerAllVariants(apple, apple.getVariants());
|
||||||
|
@ -121,6 +123,8 @@ public class UItems {
|
||||||
registerAllVariants(alfalfa_seeds, "alfalfa_seeds");
|
registerAllVariants(alfalfa_seeds, "alfalfa_seeds");
|
||||||
registerAllVariants(alfalfa_leaves, "alfalfa_leaves");
|
registerAllVariants(alfalfa_leaves, "alfalfa_leaves");
|
||||||
registerAllVariants(cereal, "cereal");
|
registerAllVariants(cereal, "cereal");
|
||||||
|
registerAllVariants(tomato, "tomato", "rotten_tomato");
|
||||||
|
registerAllVariants(cloudsdale_tomato, "cloudsdale_tomato", "rotten_cloudsdale_tomato");
|
||||||
}
|
}
|
||||||
|
|
||||||
registerFuels();
|
registerFuels();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockCrops;
|
import net.minecraft.block.BlockCrops;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
@ -10,6 +11,8 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraft.util.SoundEvent;
|
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.ColorHandlerEvent;
|
||||||
import net.minecraftforge.client.event.EntityViewRenderEvent;
|
import net.minecraftforge.client.event.EntityViewRenderEvent;
|
||||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
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.PlayerDropsEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
|
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
|
import net.minecraftforge.event.entity.player.UseHoeEvent;
|
||||||
import net.minecraftforge.event.world.BlockEvent;
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
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.FMLInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
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.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
|
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.JumpingCastle;
|
||||||
import com.minelittlepony.jumpingcastle.api.Target;
|
import com.minelittlepony.jumpingcastle.api.Target;
|
||||||
import com.minelittlepony.unicopia.advancements.UAdvancements;
|
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.EntityMagicFX;
|
||||||
import com.minelittlepony.unicopia.client.particle.EntityRaindropFX;
|
import com.minelittlepony.unicopia.client.particle.EntityRaindropFX;
|
||||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
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
|
@SubscribeEvent
|
||||||
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
||||||
if (event.phase == Phase.END) {
|
if (event.phase == Phase.END) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.EnumPlantType;
|
||||||
import net.minecraftforge.common.ForgeHooks;
|
import net.minecraftforge.common.ForgeHooks;
|
||||||
|
|
||||||
public class BlockAlfalfa extends BlockCrops {
|
public class BlockAlfalfa extends BlockCrops {
|
||||||
|
@ -116,19 +117,20 @@ public class BlockAlfalfa extends BlockCrops {
|
||||||
int max = getMaxAge();
|
int max = getMaxAge();
|
||||||
|
|
||||||
if (age > max) {
|
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;
|
age = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean hasUp = world.getBlockState(pos.up()).getBlock() == this;
|
boolean hasUp = world.getBlockState(pos.up()).getBlock() == this;
|
||||||
|
|
||||||
if (hasDown && hasUp) {
|
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) {
|
} else if (hasUp) {
|
||||||
world.setBlockState(pos, this.withAge(age).withProperty(HALF, Half.BOTTOM));
|
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.BOTTOM));
|
||||||
} else {
|
} 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);
|
return (Half)state.getValue(HALF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) {
|
||||||
|
return EnumPlantType.Crop;
|
||||||
|
}
|
||||||
|
|
||||||
public static enum Half implements IStringSerializable {
|
public static enum Half implements IStringSerializable {
|
||||||
TOP,
|
TOP,
|
||||||
MIDDLE,
|
MIDDLE,
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.CloudType;
|
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.Block;
|
||||||
import net.minecraft.block.SoundType;
|
import net.minecraft.block.SoundType;
|
||||||
|
@ -25,7 +27,7 @@ import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
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);
|
public static final PropertyEnum<CloudType> VARIANT = PropertyEnum.create("variant", CloudType.class);
|
||||||
|
|
||||||
|
@ -139,9 +141,9 @@ public class BlockCloud extends Block implements ICloudBlock {
|
||||||
@Override
|
@Override
|
||||||
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) {
|
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) {
|
||||||
if (!CloudType.NORMAL.canInteract(player)) {
|
if (!CloudType.NORMAL.canInteract(player)) {
|
||||||
return -1;
|
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
|
||||||
}
|
}
|
||||||
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -176,4 +178,15 @@ public class BlockCloud extends Block implements ICloudBlock {
|
||||||
return (CloudType)blockState.getValue(VARIANT);
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
127
src/main/java/com/minelittlepony/unicopia/block/UFarmland.java
Normal file
127
src/main/java/com/minelittlepony/unicopia/block/UFarmland.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
src/main/java/com/minelittlepony/unicopia/item/ITossable.java
Normal file
105
src/main/java/com/minelittlepony/unicopia/item/ITossable.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.UItems;
|
|
||||||
import com.minelittlepony.util.MagicalDamageSource;
|
import com.minelittlepony.util.MagicalDamageSource;
|
||||||
import com.minelittlepony.util.vector.VecHelper;
|
import com.minelittlepony.util.vector.VecHelper;
|
||||||
|
|
||||||
|
@ -63,20 +62,25 @@ public class ItemApple extends ItemFood {
|
||||||
@Override
|
@Override
|
||||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||||
RayTraceResult mop = VecHelper.getObjectMouseOver(player, 5, 0);
|
RayTraceResult mop = VecHelper.getObjectMouseOver(player, 5, 0);
|
||||||
|
|
||||||
if (mop != null && mop.typeOfHit == RayTraceResult.Type.ENTITY) {
|
if (mop != null && mop.typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||||
ItemStack stack = player.getHeldItem(hand);
|
ItemStack stack = player.getHeldItem(hand);
|
||||||
|
|
||||||
if (canFeedTo(stack, mop.entityHit)) {
|
if (canFeedTo(stack, mop.entityHit)) {
|
||||||
return onFedTo(stack, player, mop.entityHit);
|
return onFedTo(stack, player, mop.entityHit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onItemRightClick(world, player, hand);
|
return super.onItemRightClick(world, player, hand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFoodEaten(ItemStack stack, World w, EntityPlayer player) {
|
protected void onFoodEaten(ItemStack stack, World w, EntityPlayer player) {
|
||||||
super.onFoodEaten(stack, w, player);
|
super.onFoodEaten(stack, w, player);
|
||||||
|
|
||||||
if (isZapApple(stack)) {
|
if (isZapApple(stack)) {
|
||||||
player.attackEntityFrom(MagicalDamageSource.create("zap"), 120);
|
player.attackEntityFrom(MagicalDamageSource.create("zap"), 120);
|
||||||
|
|
||||||
w.addWeatherEffect(new EntityLightningBolt(w, player.posX, player.posY, player.posZ, false));
|
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) {
|
public ActionResult<ItemStack> onFedTo(ItemStack stack, EntityPlayer player, Entity e) {
|
||||||
e.onStruckByLightning(new EntityLightningBolt(e.world, e.posX, e.posY, e.posZ, false));
|
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);
|
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +111,9 @@ public class ItemApple extends ItemFood {
|
||||||
public ItemApple setSubTypes(String... types) {
|
public ItemApple setSubTypes(String... types) {
|
||||||
subTypes = types;
|
subTypes = types;
|
||||||
variants = new String[subTypes.length * 2];
|
variants = new String[subTypes.length * 2];
|
||||||
|
|
||||||
setTranslationKey(variants[0] = types[0]);
|
setTranslationKey(variants[0] = types[0]);
|
||||||
|
|
||||||
for (int i = 1; i < variants.length; i++) {
|
for (int i = 1; i < variants.length; i++) {
|
||||||
variants[i] = variants[0] + (i % subTypes.length != 0 ? "_" + subTypes[i % subTypes.length] : "");
|
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) {
|
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items) {
|
||||||
if (isInCreativeTab(tab)) {
|
if (isInCreativeTab(tab)) {
|
||||||
for (int i = 0; i < subTypes.length; i++) {
|
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
|
@Override
|
||||||
public EnumRarity getRarity(ItemStack stack) {
|
public EnumRarity getRarity(ItemStack stack) {
|
||||||
int meta = stack.getMetadata();
|
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;
|
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
|
@Override
|
||||||
public String getTranslationKey(ItemStack stack) {
|
public String getTranslationKey(ItemStack stack) {
|
||||||
int meta = stack.getMetadata() % subTypes.length;
|
int meta = Math.max(0, stack.getMetadata() % subTypes.length);
|
||||||
if (meta < 0) meta = 0;
|
|
||||||
return super.getTranslationKey(stack) + (meta > 0 ? "." + subTypes[meta] : "");
|
return super.getTranslationKey(stack) + (meta > 0 ? "." + subTypes[meta] : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,12 +60,11 @@ class PlayerGravityDelegate implements IUpdatable<EntityPlayer>, IGravity, InbtS
|
||||||
|
|
||||||
entity.fallDistance = 0;
|
entity.fallDistance = 0;
|
||||||
|
|
||||||
float exhaustion = (0.2F * ticksInAir++) / 90;
|
float exhaustion = (0.5F * ticksInAir++) / 70;
|
||||||
if (entity.isSprinting()) {
|
if (entity.isSprinting()) {
|
||||||
exhaustion *= 3.11F;
|
exhaustion *= 3.11F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
exhaustion *= (1 - flightExperience/MAXIMUM_FLIGHT_EXPERIENCE);
|
exhaustion *= (1 - flightExperience/MAXIMUM_FLIGHT_EXPERIENCE);
|
||||||
|
|
||||||
entity.addExhaustion(exhaustion);
|
entity.addExhaustion(exhaustion);
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,13 @@ package com.minelittlepony.util;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
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.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockPos.MutableBlockPos;
|
||||||
|
|
||||||
public class PosHelper {
|
public class PosHelper {
|
||||||
|
|
||||||
|
@ -22,4 +26,11 @@ public class PosHelper {
|
||||||
}
|
}
|
||||||
return false;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" }
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,10 @@ item.apple.rotten.name=Rotten Apple
|
||||||
item.apple.zap.name=Zap Apple
|
item.apple.zap.name=Zap Apple
|
||||||
item.apple.zap_cooked.name=Cooked 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_leaves.name=Alfalfa
|
||||||
item.alfalfa_seeds.name=Grain
|
item.alfalfa_seeds.name=Grain
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"parent": "block/farmland",
|
||||||
|
"textures": {
|
||||||
|
"particle": "unicopia:blocks/cloud_normal",
|
||||||
|
"dirt": "unicopia:blocks/cloud_normal",
|
||||||
|
"top": "unicopia:blocks/cloud_farmland_dry"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"parent": "block/farmland",
|
||||||
|
"textures": {
|
||||||
|
"particle": "unicopia:blocks/cloud_normal",
|
||||||
|
"dirt": "unicopia:blocks/cloud_normal",
|
||||||
|
"top": "unicopia:blocks/cloud_farmland_wet"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:items/tomato"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:items/rotten_tomato"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:items/rotten_tomato"
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 |
BIN
src/main/resources/assets/unicopia/textures/items/tomato.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/items/tomato.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3 KiB |
Loading…
Reference in a new issue