Readded cloud blocks, readded/rewrote cloud entities, improved various other stuff
49
src/main/java/com/minelittlepony/unicopia/CloudSize.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.*;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public enum CloudSize {
|
||||
SMALL(EntityRacingCloud::new),
|
||||
MEDIUM(EntityConstructionCloud::new),
|
||||
LARGE(EntityWildCloud::new);
|
||||
|
||||
private static final CloudSize[] META_LOOKUP = new CloudSize[values().length];
|
||||
static {
|
||||
CloudSize[] values = values();
|
||||
for (CloudSize i : values) {
|
||||
META_LOOKUP[i.getMetadata()] = i;
|
||||
}
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Function<World, EntityCloud> constructor;
|
||||
|
||||
CloudSize(Function<World, EntityCloud> constructor) {
|
||||
this.constructor = constructor;
|
||||
this.name = name().toLowerCase();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getMetadata() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public EntityCloud createEntity(World w) {
|
||||
return constructor.apply(w);
|
||||
}
|
||||
|
||||
public static CloudSize byMetadata(int meta) {
|
||||
if (meta < 0 || meta >= META_LOOKUP.length) {
|
||||
meta = 0;
|
||||
}
|
||||
return META_LOOKUP[meta];
|
||||
}
|
||||
}
|
93
src/main/java/com/minelittlepony/unicopia/CloudType.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum CloudType implements IStringSerializable {
|
||||
NORMAL("NORMAL", 0, "normal"),
|
||||
PACKED("PACKED", 1, "packed"),
|
||||
ENCHANTED("ENCHANTED", 2, "enchanted");
|
||||
|
||||
private String name;
|
||||
private int meta;
|
||||
private String unlocalizedName;
|
||||
|
||||
private static final CloudType[] META_LOOKUP = new CloudType[values().length];
|
||||
private static final String[] NAMES = new String[values().length];
|
||||
|
||||
static {
|
||||
for (CloudType i : values()) {
|
||||
META_LOOKUP[i.getMetadata()] = i;
|
||||
NAMES[i.ordinal()] = i.getTranslationKey();
|
||||
}
|
||||
}
|
||||
|
||||
CloudType(String name, int meta, String unlocalised) {
|
||||
this.name = name;
|
||||
this.meta = meta;
|
||||
this.unlocalizedName = unlocalised;
|
||||
}
|
||||
|
||||
public static CloudType byMetadata(int meta) {
|
||||
if (meta < 0 || meta >= META_LOOKUP.length) meta = 0;
|
||||
return META_LOOKUP[meta];
|
||||
}
|
||||
|
||||
|
||||
public static String[] getVariants(String suffex) {
|
||||
String[] result = new String[NAMES.length];
|
||||
|
||||
for (int i = 0; i < NAMES.length; i++) {
|
||||
result[i] = NAMES[i] + suffex;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return unlocalizedName;
|
||||
}
|
||||
|
||||
public String getTranslationKey() {
|
||||
return unlocalizedName;
|
||||
}
|
||||
|
||||
public int getMetadata() {
|
||||
return meta;
|
||||
}
|
||||
|
||||
public boolean canInteract(Entity e) {
|
||||
if (this == ENCHANTED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e instanceof EntityPlayer) {
|
||||
|
||||
if (this == PACKED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Predicates.INTERACT_WITH_CLOUDS.test((EntityPlayer)e)
|
||||
|| EntityCloud.getFeatherEnchantStrength((EntityPlayer)e) > 0;
|
||||
}
|
||||
|
||||
if (e instanceof EntityItem) {
|
||||
return Predicates.ITEM_INTERACT_WITH_CLOUDS.test((EntityItem)e);
|
||||
}
|
||||
|
||||
if (e instanceof EntityCloud && e.isRiding()) {
|
||||
return canInteract(e.getRidingEntity());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
39
src/main/java/com/minelittlepony/unicopia/Predicates.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public final class Predicates {
|
||||
public static final Predicate<EntityPlayer> INTERACT_WITH_CLOUDS = player -> {
|
||||
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds();
|
||||
};
|
||||
public static final Predicate<EntityItem> ITEM_INTERACT_WITH_CLOUDS = item -> {
|
||||
return item != null && PlayerSpeciesList.instance().getEntity(item).getPlayerSpecies().canInteractWithClouds();
|
||||
};
|
||||
|
||||
public static final Predicate<Entity> ENTITY_INTERACT_WITH_CLOUDS = entity -> {
|
||||
return entity != null && (
|
||||
(entity instanceof EntityPlayer && INTERACT_WITH_CLOUDS.test((EntityPlayer)entity))
|
||||
|| (entity instanceof EntityItem && ITEM_INTERACT_WITH_CLOUDS.test((EntityItem)entity))
|
||||
);
|
||||
};
|
||||
|
||||
public static EntityPlayer getPlayerFromEntity(Entity entity) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
return (EntityPlayer) entity;
|
||||
}
|
||||
|
||||
if (entity instanceof EntityItem) {
|
||||
EntityItem item = (EntityItem)entity;
|
||||
if (item.getOwner() != null) {
|
||||
return item.getEntityWorld().getPlayerEntityByName(item.getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -48,6 +48,10 @@ public enum Race {
|
|||
return earth;
|
||||
}
|
||||
|
||||
public boolean canInteractWithClouds() {
|
||||
return canFly() && this != CHANGELING;
|
||||
}
|
||||
|
||||
public String getDisplayString() {
|
||||
return I18n.format(getTranslationString());
|
||||
}
|
||||
|
@ -62,7 +66,7 @@ public enum Race {
|
|||
|| getDisplayString().equalsIgnoreCase(s);
|
||||
}
|
||||
|
||||
public static Race fromName(String s) {
|
||||
public static Race fromName(String s, Race def) {
|
||||
if (!Strings.isNullOrEmpty(s)) {
|
||||
for (Race i : values()) {
|
||||
if (i.isSameAs(s)) return i;
|
||||
|
@ -73,7 +77,7 @@ public enum Race {
|
|||
return fromId(Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) { }
|
||||
|
||||
return HUMAN;
|
||||
return def;
|
||||
}
|
||||
|
||||
public static Race fromId(int id) {
|
||||
|
|
21
src/main/java/com/minelittlepony/unicopia/UBlocks.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.minelittlepony.unicopia.block.BlockCloud;
|
||||
import com.minelittlepony.unicopia.block.BlockCloudSlab;
|
||||
import com.minelittlepony.unicopia.block.BlockCloudStairs;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
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 BlockCloudSlab cloud_double_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");
|
||||
|
||||
static void registerBlocks(IForgeRegistry<Block> registry) {
|
||||
registry.registerAll(cloud, stairsCloud, cloud_double_slab, cloud_slab);
|
||||
}
|
||||
}
|
34
src/main/java/com/minelittlepony/unicopia/UEntities.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
||||
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
|
||||
import com.minelittlepony.unicopia.entity.EntityWildCloud;
|
||||
import com.minelittlepony.unicopia.render.RenderCloud;
|
||||
|
||||
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.registries.IForgeRegistry;
|
||||
|
||||
public class UEntities {
|
||||
private static final int BRUSHES_ROYALBLUE = 4286945;
|
||||
private static final int BRUSHES_CHARTREUSE = 8388352;
|
||||
|
||||
static void init(IForgeRegistry<EntityEntry> registry) {
|
||||
EntityEntry entry = new EntityEntry(EntityCloud.class, "cloud").setRegistryName(Unicopia.MODID, "cloud");
|
||||
|
||||
entry.setEgg(new EntityEggInfo(new ResourceLocation("unicopia", "cloud"), BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE));
|
||||
|
||||
registry.register(entry);
|
||||
|
||||
registry.register(new EntityEntry(EntityWildCloud.class, "wild_cloud").setRegistryName(Unicopia.MODID, "wild_cloud"));
|
||||
registry.register(new EntityEntry(EntityRacingCloud.class, "racing_cloud").setRegistryName(Unicopia.MODID, "racing_cloud"));
|
||||
registry.register(new EntityEntry(EntityConstructionCloud.class, "construction_cloud").setRegistryName(Unicopia.MODID, "construction_cloud"));
|
||||
}
|
||||
|
||||
static void preInit() {
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, manager -> new RenderCloud(manager));
|
||||
}
|
||||
}
|
|
@ -1,38 +1,77 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.minelittlepony.unicopia.item.ItemApple;
|
||||
import com.minelittlepony.unicopia.item.ItemCloud;
|
||||
import com.minelittlepony.unicopia.item.UItemBlock;
|
||||
import com.minelittlepony.unicopia.item.UItemMultiTexture;
|
||||
import com.minelittlepony.unicopia.item.UItemSlab;
|
||||
|
||||
import come.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.FurnaceRecipes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import static com.minelittlepony.unicopia.Predicates.*;
|
||||
|
||||
public class UItems {
|
||||
public static final ItemApple apple = new ItemApple()
|
||||
.setSubTypes("apple", "green", "sweet", "rotten", "zap", "zap_cooked")
|
||||
.setTypeRarities(10, 20, 10, 30);
|
||||
|
||||
static void registerItems() {
|
||||
public static final Item cloud_matter = new Item()
|
||||
.setCreativeTab(CreativeTabs.MATERIALS)
|
||||
.setTranslationKey("cloud_matter")
|
||||
.setRegistryName(Unicopia.MODID, "cloud_matter");
|
||||
|
||||
public static final Item dew_drop = new Item()
|
||||
.setCreativeTab(CreativeTabs.MATERIALS)
|
||||
.setTranslationKey("dew_drop")
|
||||
.setRegistryName(Unicopia.MODID, "dew_drop");
|
||||
|
||||
public static final ItemCloud cloud_spawner = new ItemCloud(Unicopia.MODID, "cloud");
|
||||
|
||||
public static final Item cloud_block = new UItemMultiTexture(UBlocks.cloud, stack -> {
|
||||
return CloudType.byMetadata(stack.getMetadata()).getTranslationKey();
|
||||
}, INTERACT_WITH_CLOUDS).setRegistryName(Unicopia.MODID, "cloud_block");
|
||||
|
||||
public static final Item cloud_stairs = new UItemBlock(UBlocks.stairsCloud, INTERACT_WITH_CLOUDS)
|
||||
.setTranslationKey("cloud_stairs")
|
||||
.setRegistryName(Unicopia.MODID, "cloud_stairs");
|
||||
|
||||
public static final Item cloud_slab = new UItemSlab(UBlocks.cloud_slab, UBlocks.cloud_slab, UBlocks.cloud_double_slab, INTERACT_WITH_CLOUDS)
|
||||
.setTranslationKey("cloud_slab")
|
||||
.setRegistryName(Unicopia.MODID, "cloud_slab");
|
||||
|
||||
static void registerItems(IForgeRegistry<Item> registry) {
|
||||
RegistryLockSpinner.unlock(Item.REGISTRY);
|
||||
|
||||
ResourceLocation res = new ResourceLocation("apple");
|
||||
|
||||
Item.REGISTRY.register(Item.getIdFromItem(Items.APPLE), res, apple);
|
||||
|
||||
if (UClient.isClientSide()) {
|
||||
String[] variants = apple.getVariants();
|
||||
|
||||
for (int i = 0; i < variants.length; i++) {
|
||||
ModelLoader.setCustomModelResourceLocation(apple, i, new ModelResourceLocation("unicopia:" + variants[i]));
|
||||
}
|
||||
// ModelBakery.registerItemVariants(apple, NoNameSpacedResource.ofAllDomained("unicopia", apple.getVariants()));
|
||||
}
|
||||
Item.REGISTRY.register(Item.getIdFromItem(Items.APPLE), new ResourceLocation("apple"), apple);
|
||||
|
||||
RegistryLockSpinner.lock(Item.REGISTRY);
|
||||
|
||||
registry.registerAll(cloud_spawner, dew_drop, cloud_matter, cloud_block, cloud_stairs, cloud_slab);
|
||||
|
||||
if (UClient.isClientSide()) {
|
||||
registerAllVariants(apple, apple.getVariants());
|
||||
registerAllVariants(cloud_spawner, "cloud_small", "cloud_medium", "cloud_large");
|
||||
registerAllVariants(dew_drop, "dew_drop");
|
||||
registerAllVariants(cloud_matter, "cloud_matter");
|
||||
registerAllVariants(cloud_stairs, "cloud_stairs");
|
||||
registerAllVariants(cloud_slab, CloudType.getVariants("_cloud_slab"));
|
||||
registerAllVariants(cloud_block, CloudType.getVariants("_cloud_block"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerAllVariants(Item item, String... variants) {
|
||||
for (int i = 0; i < variants.length; i++) {
|
||||
ModelLoader.setCustomModelResourceLocation(item, i, new ModelResourceLocation("unicopia:" + variants[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void registerFuels() {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
||||
public class UMaterials {
|
||||
public static final Material cloud = (new Material(MapColor.SNOW));
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraftforge.client.event.EntityViewRenderEvent;
|
||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerDropsEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
|
@ -19,6 +22,7 @@ import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
|||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
|
||||
import net.minecraftforge.fml.common.registry.EntityEntry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
|
@ -26,6 +30,7 @@ import com.minelittlepony.jumpingcastle.api.IChannel;
|
|||
import com.minelittlepony.jumpingcastle.api.JumpingCastle;
|
||||
import com.minelittlepony.jumpingcastle.api.Target;
|
||||
import com.minelittlepony.unicopia.client.particle.EntityMagicFX;
|
||||
import com.minelittlepony.unicopia.client.particle.EntityRaindropFX;
|
||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
||||
import com.minelittlepony.unicopia.command.Commands;
|
||||
import com.minelittlepony.unicopia.input.Keyboard;
|
||||
|
@ -47,10 +52,13 @@ public class Unicopia {
|
|||
public static IChannel channel;
|
||||
|
||||
public static int MAGIC_PARTICLE;
|
||||
public static int RAIN_PARTICLE;
|
||||
|
||||
@EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
|
||||
if (UClient.isClientSide()) {
|
||||
UEntities.preInit();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -68,6 +76,7 @@ public class Unicopia {
|
|||
.consume(MsgPlayerAbility.class);
|
||||
|
||||
MAGIC_PARTICLE = Particles.instance().registerParticle(new EntityMagicFX.Factory());
|
||||
RAIN_PARTICLE = Particles.instance().registerParticle(new EntityRaindropFX.Factory());
|
||||
|
||||
PowersRegistry.instance().init();
|
||||
|
||||
|
@ -76,7 +85,17 @@ public class Unicopia {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void registerItemsStatic(RegistryEvent.Register<Item> event) {
|
||||
UItems.registerItems();
|
||||
UItems.registerItems(event.getRegistry());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerBlocksStatic(RegistryEvent.Register<Block> event) {
|
||||
UBlocks.registerBlocks(event.getRegistry());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerEntitiesStatic(RegistryEvent.Register<EntityEntry> event) {
|
||||
UEntities.init(event.getRegistry());
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
@ -96,6 +115,23 @@ public class Unicopia {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTossItem(ItemTossEvent event) {
|
||||
Race race = PlayerSpeciesList.instance().getPlayer(event.getPlayer()).getPlayerSpecies();
|
||||
|
||||
PlayerSpeciesList.instance().getEntity(event.getEntityItem()).setPlayerSpecies(race);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerDropItems(PlayerDropsEvent event) {
|
||||
|
||||
Race race = PlayerSpeciesList.instance().getPlayer(event.getEntityPlayer()).getPlayerSpecies();
|
||||
|
||||
event.getDrops().stream().map(PlayerSpeciesList.instance()::getEntity).forEach(item -> {
|
||||
item.setPlayerSpecies(race);
|
||||
});
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerFall(PlayerFlyableFallEvent event) {
|
||||
PlayerSpeciesList.instance()
|
||||
|
@ -119,12 +155,12 @@ public class Unicopia {
|
|||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void modifyFOV(EntityViewRenderEvent.FOVModifier event) {
|
||||
float fov = event.getFOV();
|
||||
public static void modifyFOV(FOVUpdateEvent event) {
|
||||
float fov = event.getFov();
|
||||
|
||||
fov += PlayerSpeciesList.instance().getPlayer(Minecraft.getMinecraft().player).getExertion() * 5;
|
||||
fov += PlayerSpeciesList.instance().getPlayer(event.getEntity()).getExertion() / 5;
|
||||
|
||||
event.setFOV(fov);
|
||||
event.setNewfov(fov);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
186
src/main/java/com/minelittlepony/unicopia/block/BlockCloud.java
Normal file
|
@ -0,0 +1,186 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.CloudType;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockCloud extends Block implements ICloudBlock {
|
||||
|
||||
public static final PropertyEnum<CloudType> VARIANT = PropertyEnum.create("variant", CloudType.class);
|
||||
|
||||
public BlockCloud(Material material, String domain, String name) {
|
||||
super(material);
|
||||
setCreativeTab(CreativeTabs.MISC);
|
||||
setHardness(0.5f);
|
||||
setResistance(1.0F);
|
||||
setSoundType(SoundType.CLOTH);
|
||||
setRegistryName(domain, name);
|
||||
setLightOpacity(20);
|
||||
setTranslationKey(name);
|
||||
useNeighborBrightness = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucent(IBlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
//Push player out of block
|
||||
public boolean isFullCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNormalCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) {
|
||||
return super.shouldSideBeRendered(blockState, blockAccess, pos, side);
|
||||
}
|
||||
|
||||
@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 (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.doesSideBlockRendering(state, world, pos, face);
|
||||
}
|
||||
|
||||
//Can entities walk through?
|
||||
@Override
|
||||
public boolean isPassable(IBlockAccess w, BlockPos pos) {
|
||||
return super.isPassable(w, pos);
|
||||
}
|
||||
|
||||
@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 -1;
|
||||
}
|
||||
return super.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state) {
|
||||
return ((CloudType)state.getValue(VARIANT)).getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
for (CloudType i : CloudType.values()) {
|
||||
list.add(new ItemStack(this, 1, i.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
return getDefaultState().withProperty(VARIANT, CloudType.byMetadata(meta));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return ((CloudType)state.getValue(VARIANT)).getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, new IProperty[] {VARIANT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudType getCloudMaterialType(IBlockState blockState) {
|
||||
return (CloudType)blockState.getValue(VARIANT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.CloudType;
|
||||
import com.minelittlepony.unicopia.UBlocks;
|
||||
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockCloudSlab extends BlockSlab implements ICloudBlock {
|
||||
|
||||
public static final PropertyEnum<CloudType> VARIANT = PropertyEnum.create("variant", CloudType.class);
|
||||
|
||||
private boolean isDouble;
|
||||
|
||||
public BlockCloudSlab(boolean isDouble, Material material, String domain, String name) {
|
||||
super(material);
|
||||
setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
|
||||
setHardness(0.5F);
|
||||
setResistance(1.0F);
|
||||
setSoundType(SoundType.CLOTH);
|
||||
setLightOpacity(20);
|
||||
setTranslationKey(name);
|
||||
setRegistryName(domain, name);
|
||||
this.isDouble = isDouble;
|
||||
useNeighborBrightness = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucent(IBlockState state) {
|
||||
return UBlocks.cloud.isTranslucent(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return isDouble() ? UBlocks.cloud.isOpaqueCube(state) : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube(IBlockState state) {
|
||||
return isDouble() ? UBlocks.cloud.isFullCube(state) : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNormalCube(IBlockState state) {
|
||||
return isDouble() ? UBlocks.cloud.isNormalCube(state) : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return UBlocks.cloud.getRenderLayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos) {
|
||||
return super.isPassable(worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFallenUpon(World w, BlockPos pos, Entity entity, float fallDistance) {
|
||||
UBlocks.cloud.onFallenUpon(w, pos, entity, fallDistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLanded(World w, Entity entity) {
|
||||
UBlocks.cloud.onLanded(w, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollision(World w, BlockPos pos, IBlockState state, Entity entity) {
|
||||
UBlocks.cloud.onEntityCollision(w, pos, state, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@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) {
|
||||
return UBlocks.cloud.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
|
||||
}
|
||||
|
||||
@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 (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) {
|
||||
if (isDouble) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (face == EnumFacing.UP || face == EnumFacing.DOWN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (beside.getBlock() == this) {
|
||||
return beside.getValue(HALF) == state.getValue(HALF);
|
||||
} else {
|
||||
if (beside.getBlock() instanceof BlockCloudStairs) {
|
||||
return beside.getValue(BlockStairs.HALF).ordinal() == state.getValue(HALF).ordinal()
|
||||
&& beside.getValue(BlockStairs.FACING) == face;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) {
|
||||
return UBlocks.cloud.canEntityDestroy(state, world, pos, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(IBlockState state, Random rand, int fortune) {
|
||||
return Item.getItemFromBlock(UBlocks.cloud_slab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) {
|
||||
return new ItemStack(Item.getItemFromBlock(UBlocks.cloud_slab), 2, getMetaFromState(state));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(int meta) {
|
||||
return super.getTranslationKey() + "." + CloudType.byMetadata(meta).getTranslationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProperty<CloudType> getVariantProperty() {
|
||||
return VARIANT;
|
||||
}
|
||||
|
||||
public Object getVariant(ItemStack stack) {
|
||||
return CloudType.byMetadata(stack.getMetadata() & 7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
for (CloudType i : CloudType.values()) {
|
||||
list.add(new ItemStack(this, 1, i.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CloudType getCloudMaterialType(IBlockState blockState) {
|
||||
return (CloudType)blockState.getValue(VARIANT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
IBlockState state = getDefaultState().withProperty(VARIANT, CloudType.byMetadata(meta & 7));
|
||||
if (!isDouble()) {
|
||||
state = state.withProperty(HALF, (meta & 8) == 0 ? BlockSlab.EnumBlockHalf.BOTTOM : BlockSlab.EnumBlockHalf.TOP);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
byte mask = 0;
|
||||
int result = mask | getCloudMaterialType(state).getMetadata();
|
||||
if (!isDouble() && state.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP) {
|
||||
result |= 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, isDouble() ?
|
||||
new IProperty[] {VARIANT}
|
||||
: new IProperty[] {HALF, VARIANT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state) {
|
||||
return getCloudMaterialType(state).getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDouble() {
|
||||
return isDouble;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparable<CloudType> getTypeForItem(ItemStack stack) {
|
||||
return CloudType.byMetadata(stack.getMetadata() & 7);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.CloudType;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
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 BlockCloudStairs extends BlockStairs implements ICloudBlock {
|
||||
|
||||
protected Block theBlock;
|
||||
protected IBlockState theState;
|
||||
|
||||
public BlockCloudStairs(IBlockState inherited, String domain, String name) {
|
||||
super(inherited);
|
||||
setTranslationKey(name);
|
||||
setRegistryName(domain, name);
|
||||
theBlock = inherited.getBlock();
|
||||
theState = inherited;
|
||||
useNeighborBrightness = true;
|
||||
|
||||
fullBlock = isOpaqueCube(inherited);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isTranslucent(IBlockState state) {
|
||||
return theBlock.isTranslucent(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isNormalCube(IBlockState state) {
|
||||
return theBlock.isNormalCube(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos) {
|
||||
return theBlock.isPassable(worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFallenUpon(World w, BlockPos pos, Entity entity, float fallDistance) {
|
||||
theBlock.onFallenUpon(w, pos, entity, fallDistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLanded(World w, Entity entity) {
|
||||
theBlock.onLanded(w, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollision(World w, BlockPos pos, IBlockState state, Entity entity) {
|
||||
theBlock.onEntityCollision(w, pos, theState, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityWalk(World w, BlockPos pos, Entity entity) {
|
||||
theBlock.onEntityWalk(w, pos, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entity, boolean p_185477_7_) {
|
||||
if (getCanInteract(theState, entity)) {
|
||||
super.addCollisionBoxToList(state, worldIn, pos, entityBox, collidingBoxes, entity, p_185477_7_);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) {
|
||||
return theBlock.canEntityDestroy(state, world, pos, entity);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) {
|
||||
return theBlock.getPlayerRelativeBlockHardness(state, player, worldIn, pos);
|
||||
}
|
||||
|
||||
@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());
|
||||
|
||||
EnumFacing front = state.getValue(FACING);
|
||||
EnumHalf half = state.getValue(HALF);
|
||||
|
||||
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) {
|
||||
if (beside.getBlock() == this) {
|
||||
EnumFacing bfront = beside.getValue(FACING);
|
||||
EnumHalf bhalf = beside.getValue(HALF);
|
||||
|
||||
return (bfront == front && front != face && half == bhalf)
|
||||
|| (bfront.getOpposite() == front && front == face);
|
||||
} else {
|
||||
if (beside.getBlock() instanceof BlockCloudSlab) {
|
||||
return beside.getValue(BlockSlab.HALF).ordinal() == half.ordinal();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudType getCloudMaterialType(IBlockState blockState) {
|
||||
return CloudType.NORMAL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import com.minelittlepony.unicopia.CloudType;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface ICloudBlock {
|
||||
|
||||
CloudType getCloudMaterialType(IBlockState blockState);
|
||||
|
||||
default boolean getCanInteract(IBlockState state, Entity e) {
|
||||
return getCloudMaterialType(state).canInteract(e);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.minelittlepony.unicopia.client.particle;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
public class EntityParticleEmitter {
|
||||
|
||||
public void emitDestructionParticles(Entity e, IBlockState blockState) {
|
||||
float f = 0.1f;
|
||||
int total = 64 * (int)(e.width * e.height * e.width);
|
||||
for (int i = 0; i < total; i++) {
|
||||
double x = MathHelper.nextDouble(e.getEntityWorld().rand, e.posX - e.width/2 - f, e.posX + e.width/2 + f);
|
||||
double y = MathHelper.nextDouble(e.getEntityWorld().rand, e.posY - f, e.posY + e.height + f);
|
||||
double z = MathHelper.nextDouble(e.getEntityWorld().rand, e.posZ - e.width/2 - f, e.posZ + e.width/2 + f);
|
||||
spawnDigginFX(e.getEntityWorld(), x, y, z, x - (int)x - 0.5, y - (int)y - 0.5, z - (int)z - 0.5, blockState, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void emitDiggingParticles(Entity e, IBlockState blockState) {
|
||||
for (int side = 0; side < 6; side++) {
|
||||
addBlockHitEffectsToEntity(e, blockState, side);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBlockHitEffectsToEntity(Entity e, IBlockState blockState, int side) {
|
||||
side = side % 6;
|
||||
float f = 0.25f;
|
||||
double x = MathHelper.nextDouble(e.getEntityWorld().rand, e.posX - e.width/2 - f, e.posX + e.width/2 + f);
|
||||
double y = MathHelper.nextDouble(e.getEntityWorld().rand, e.posY - f, e.posY + e.height + f);
|
||||
double z = MathHelper.nextDouble(e.getEntityWorld().rand, e.posZ - e.width/2 - f, e.posZ + e.width/2 + f);
|
||||
|
||||
double vX = 0;
|
||||
double vY = 0;
|
||||
double vZ = 0;
|
||||
|
||||
if (side == 0) y = e.posY - f;
|
||||
if (side == 1) {
|
||||
y = e.posY + e.height + f;
|
||||
vY += 0.5;
|
||||
}
|
||||
if (side == 2) {
|
||||
z = e.posZ - e.width/2 - f;
|
||||
vZ -= 0.5;
|
||||
}
|
||||
if (side == 3) {
|
||||
z = e.posZ + e.width/2 + f;
|
||||
vZ += 0.5;
|
||||
}
|
||||
if (side == 4) {
|
||||
x = e.posX - e.width/2 - f;
|
||||
vX -= 0.5;
|
||||
}
|
||||
if (side == 5) {
|
||||
x = e.posX + e.width/2 + f;
|
||||
vX += 0.5;
|
||||
}
|
||||
|
||||
spawnDigginFX(e.getEntityWorld(), x, y, z, vX, vY, vZ, blockState, 0.2F, 0.6F);
|
||||
}
|
||||
|
||||
protected void spawnDigginFX(World w, double x, double y, double z, double vX, double vY, double vZ, IBlockState blockState, float multScale, float multVel) {
|
||||
if (w instanceof WorldServer) {
|
||||
((WorldServer)w).spawnParticle(EnumParticleTypes.BLOCK_CRACK, false, x, y, z, 1, 0, 0, 0, Math.sqrt(vX * vX + vY * vY + vZ * vZ) * multVel, Block.getStateId(blockState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.minelittlepony.unicopia.client.particle;
|
||||
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleRain;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityRaindropFX extends ParticleRain {
|
||||
|
||||
public EntityRaindropFX(World w, double x, double y, double z) {
|
||||
super(w, x, y, z);
|
||||
motionY = -0.1;
|
||||
particleMaxAge += 19;
|
||||
}
|
||||
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
|
||||
if (onGround) {
|
||||
motionX *= 0.30000001192092896D;
|
||||
motionY = Math.random() * 0.20000000298023224D + 0.10000000149011612D;
|
||||
motionZ *= 0.30000001192092896D;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements IParticleFactory {
|
||||
@Override
|
||||
public Particle createParticle(int id, World w, double x, double y, double z, double vX, double vY, double vZ, int... args) {
|
||||
return new EntityRaindropFX(w, x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -20,6 +20,12 @@ public class Particles {
|
|||
|
||||
private final List<IParticleFactory> registeredParticles = new ArrayList<>();
|
||||
|
||||
private final EntityParticleEmitter entityEmitter = new EntityParticleEmitter();
|
||||
|
||||
public EntityParticleEmitter getEntityEmitter() {
|
||||
return entityEmitter;
|
||||
}
|
||||
|
||||
public int registerParticle(IParticleFactory factory) {
|
||||
int id = registeredParticles.size();
|
||||
registeredParticles.add(factory);
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.command.CommandBase;
|
|||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -34,12 +35,7 @@ class CommandSpecies extends CommandBase {
|
|||
|
||||
private String getRacesString() {
|
||||
String values = "";
|
||||
for (Race i : Race.values()) {
|
||||
if (PlayerSpeciesList.instance().speciesPermitted(i)) {
|
||||
if (values != "") values += ", ";
|
||||
values += i.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -55,7 +51,9 @@ class CommandSpecies extends CommandBase {
|
|||
EntityPlayerMP player;
|
||||
int playerIndex = 1;
|
||||
|
||||
if (args[0].contentEquals("set")) playerIndex++;
|
||||
if (args[0].contentEquals("set") || args[0].contentEquals("describe")) {
|
||||
playerIndex++;
|
||||
}
|
||||
|
||||
if (args.length > playerIndex) {
|
||||
player = getPlayer(server, sender, args[playerIndex]);
|
||||
|
@ -63,27 +61,25 @@ class CommandSpecies extends CommandBase {
|
|||
player = getCommandSenderAsPlayer(sender);
|
||||
}
|
||||
|
||||
if (args[0].contentEquals("set")) {
|
||||
if (args.length >= 2) {
|
||||
Race species = Race.fromName(args[1]);
|
||||
if (args[0].contentEquals("set") && args.length >= 2) {
|
||||
Race species = Race.fromName(args[1], null);
|
||||
|
||||
if (species == null) {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.fail", args[1].toUpperCase()));
|
||||
if (species == null) {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.fail", args[1].toUpperCase()));
|
||||
} else {
|
||||
if (PlayerSpeciesList.instance().speciesPermitted(species, player)) {
|
||||
PlayerSpeciesList.instance().getPlayer(player).setPlayerSpecies(species);
|
||||
|
||||
TextComponentTranslation formattedName = new TextComponentTranslation(species.name().toLowerCase());
|
||||
|
||||
if (player != sender) {
|
||||
notifyCommandListener(sender, this, 1, "commands.race.success.other", player.getName(), formattedName);
|
||||
} else {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.success.self"));
|
||||
notifyCommandListener(sender, this, 1, "commands.race.success.otherself", player.getName(), formattedName);
|
||||
}
|
||||
} else {
|
||||
if (PlayerSpeciesList.instance().speciesPermitted(species)) {
|
||||
PlayerSpeciesList.instance().getPlayer(player).setPlayerSpecies(species);
|
||||
|
||||
TextComponentTranslation formattedName = new TextComponentTranslation(species.name().toLowerCase());
|
||||
|
||||
if (player != sender) {
|
||||
notifyCommandListener(sender, this, 1, "commands.race.success.other", player.getName(), formattedName);
|
||||
} else {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.success.self"));
|
||||
notifyCommandListener(sender, this, 1, "commands.race.success.otherself", player.getName(), formattedName);
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.permission"));
|
||||
}
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.permission"));
|
||||
}
|
||||
}
|
||||
} else if (args[0].contentEquals("get")) {
|
||||
|
@ -104,29 +100,68 @@ class CommandSpecies extends CommandBase {
|
|||
} else if (args[0].contentEquals("list")) {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.list"));
|
||||
|
||||
ITextComponent message = new TextComponentString(" " + getRacesString());
|
||||
ITextComponent message = new TextComponentString(getRacesString());
|
||||
|
||||
boolean first = true;
|
||||
for (Race i : Race.values()) {
|
||||
if (PlayerSpeciesList.instance().speciesPermitted(i, player)) {
|
||||
message.appendSibling(new TextComponentString((!first ? "\n" : "") + " - " + i.name().toLowerCase()));
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
message.getStyle().setColor(TextFormatting.GOLD);
|
||||
|
||||
player.sendMessage(message);
|
||||
}
|
||||
} else if (args[0].contentEquals("describe") && args.length >= 2) {
|
||||
Race species = Race.fromName(args[1], null);
|
||||
|
||||
if (species == null) {
|
||||
player.sendMessage(new TextComponentTranslation("commands.race.fail", args[1].toUpperCase()));
|
||||
} else {
|
||||
String name = species.name().toLowerCase();
|
||||
|
||||
ITextComponent line1 = new TextComponentTranslation(String.format("commands.race.describe.%s.1", name));
|
||||
line1.getStyle().setColor(TextFormatting.YELLOW);
|
||||
|
||||
player.sendMessage(line1);
|
||||
|
||||
player.sendMessage(new TextComponentTranslation(String.format("commands.race.describe.%s.2", name)));
|
||||
|
||||
ITextComponent line3 = new TextComponentTranslation(String.format("commands.race.describe.%s.3", name));
|
||||
line3.getStyle().setColor(TextFormatting.RED);
|
||||
|
||||
player.sendMessage(line3);
|
||||
}
|
||||
} else {
|
||||
throw new WrongUsageException(getUsage(sender));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the strings available in this command to the given list of tab completion options.
|
||||
*/
|
||||
public List<String> getTabCompletions(MinecraftServer server, ICommandSender par1ICommandSender, String[] args, BlockPos pos) {
|
||||
public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, BlockPos pos) {
|
||||
|
||||
if (args.length == 1) {
|
||||
return getListOfStringsMatchingLastWord(args, new String[] { "get", "set", "list" });
|
||||
} else if (args.length == 2 && args[0].contentEquals("set")) {
|
||||
return getListOfStringsMatchingLastWord(args, "get", "set", "list", "describe");
|
||||
}
|
||||
|
||||
if (args.length == 2 && (args[0].contentEquals("set") || args[0].contentEquals("describe"))) {
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
|
||||
EntityPlayer player = sender instanceof EntityPlayer ? (EntityPlayer)sender : null;
|
||||
|
||||
for (Race i : Race.values()) {
|
||||
if (PlayerSpeciesList.instance().speciesPermitted(i)) {
|
||||
names.add(i.toString());
|
||||
if (args[0].contentEquals("describe") || PlayerSpeciesList.instance().speciesPermitted(i, player)) {
|
||||
names.add(i.name().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return getListOfStringsMatchingLastWord(args, names.toArray(new String[names.size()]));
|
||||
} else if ((args.length == 3 && args[0].contentEquals("set")) || (args[0].contentEquals("get") && args.length == 2)) {
|
||||
}
|
||||
|
||||
if ((args.length == 3 && args[0].contentEquals("set")) || (args[0].contentEquals("get") && args.length == 2)) {
|
||||
return getListOfStringsMatchingLastWord(args, server.getOnlinePlayerNames());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,670 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.UBlocks;
|
||||
import com.minelittlepony.unicopia.UItems;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
import net.minecraft.block.BlockCrops;
|
||||
import net.minecraft.block.BlockFarmland;
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityFlying;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.passive.IAnimals;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Enchantments;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemSpade;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemSword;
|
||||
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.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityCloud extends EntityFlying implements IAnimals {
|
||||
|
||||
private double altitude;
|
||||
|
||||
private final double baseWidth = 3f;
|
||||
private final double baseHeight = 0.8f;
|
||||
|
||||
public EntityCloud(World world) {
|
||||
super(world);
|
||||
preventEntitySpawning = false;
|
||||
ignoreFrustumCheck = true;
|
||||
|
||||
if (world.rand.nextInt(20) == 0 && canRainHere()) {
|
||||
setRaining();
|
||||
if (world.rand.nextInt(20) == 0) {
|
||||
setIsThundering(true);
|
||||
}
|
||||
}
|
||||
|
||||
setCloudSize(1 + rand.nextInt(3));
|
||||
}
|
||||
|
||||
private static final DataParameter<Integer> RAINTIMER = EntityDataManager.createKey(EntityCloud.class, DataSerializers.VARINT);
|
||||
private static final DataParameter<Boolean> THUNDERING = EntityDataManager.createKey(EntityCloud.class, DataSerializers.BOOLEAN);
|
||||
private static final DataParameter<Integer> SCALE = EntityDataManager.createKey(EntityCloud.class, DataSerializers.VARINT);
|
||||
|
||||
private static final DataParameter<Boolean> STATIONARY = EntityDataManager.createKey(EntityCloud.class, DataSerializers.BOOLEAN);
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
dataManager.register(RAINTIMER, 0);
|
||||
dataManager.register(THUNDERING, false);
|
||||
dataManager.register(STATIONARY, false);
|
||||
dataManager.register(SCALE, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getHurtSound(DamageSource damageSource) {
|
||||
return SoundEvents.BLOCK_CLOTH_HIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getDeathSound() {
|
||||
return SoundEvents.BLOCK_CLOTH_STEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem() {
|
||||
return UItems.cloud_matter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canTriggerWalking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesEntityNotTriggerPressurePlate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRenderOnFire() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightnessForRender() {
|
||||
return 15728640;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn() {
|
||||
return !hasCustomName() && !getStationary() && !getOpaque();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSpawnedInChunk() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStruckByLightning(EntityLightningBolt lightningBolt) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collideWithEntity(Entity other) {
|
||||
if (other instanceof EntityCloud) {
|
||||
super.collideWithEntity(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collideWithNearbyEntities() {
|
||||
|
||||
}
|
||||
|
||||
protected void checkLocation() {
|
||||
if (posY < world.provider.getCloudHeight() - 18) {
|
||||
setLocationAndAngles(posX, world.provider.getCloudHeight() - 18, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
super.collideWithNearbyEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEntityCollision(Entity other) {
|
||||
if (other instanceof EntityPlayer) {
|
||||
if (Predicates.INTERACT_WITH_CLOUDS.test((EntityPlayer)other)) {
|
||||
super.applyEntityCollision(other);
|
||||
}
|
||||
} else if (other instanceof EntityCloud) {
|
||||
super.applyEntityCollision(other);
|
||||
}
|
||||
}
|
||||
|
||||
public static double randomIn(Random rand, double min, double max) {
|
||||
return ((max - min) * rand.nextFloat());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
AxisAlignedBB boundingbox = getEntityBoundingBox();
|
||||
|
||||
if (getIsRaining()) {
|
||||
if (world.isRemote) {
|
||||
for (int i = 0; i < 30 * getCloudSize(); i++) {
|
||||
double x = posX + randomIn(rand, boundingbox.minX, boundingbox.maxX) - width / 2;
|
||||
double y = getEntityBoundingBox().minY + height/2;
|
||||
double z = posZ + randomIn(rand, boundingbox.minX, boundingbox.maxX) - width / 2;
|
||||
|
||||
int particleId = canSnowHere(new BlockPos(x, y, z)) ? EnumParticleTypes.SNOW_SHOVEL.getParticleID() : Unicopia.RAIN_PARTICLE;
|
||||
|
||||
Particles.instance().spawnParticle(particleId, false, x, y, z, 0, 0, 0);
|
||||
}
|
||||
|
||||
AxisAlignedBB rainedArea = boundingbox
|
||||
.expand(1, 0, 1)
|
||||
.expand(0, -(posY - getGroundPosition(posX, posZ).getY()), 0);
|
||||
|
||||
for (EntityPlayer j : world.getEntitiesWithinAABB(EntityPlayer.class, rainedArea)) {
|
||||
j.world.playSound(j, j.getPosition(), SoundEvents.WEATHER_RAIN, SoundCategory.AMBIENT, 0.1F, 0.6F);
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos pos = getGroundPosition(
|
||||
posX + rand.nextFloat() * width,
|
||||
posZ + rand.nextFloat() * width
|
||||
);
|
||||
|
||||
if (getIsThundering()) {
|
||||
if (rand.nextInt(3000) == 0) {
|
||||
spawnThunderbolt(pos);
|
||||
}
|
||||
|
||||
if (rand.nextInt(200) == 0) {
|
||||
setIsThundering(false);
|
||||
}
|
||||
}
|
||||
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
|
||||
if (state.getBlock() instanceof BlockFire) {
|
||||
world.setBlockState(pos, Blocks.AIR.getDefaultState());
|
||||
}
|
||||
|
||||
if (rand.nextInt(20) == 0) {
|
||||
BlockPos below = pos.down();
|
||||
state = world.getBlockState(below);
|
||||
if (state.getBlock() != null) {
|
||||
if (world.canBlockFreezeWater(below)) {
|
||||
world.setBlockState(below, Blocks.ICE.getDefaultState());
|
||||
}
|
||||
|
||||
if (world.canSnowAt(pos, false)) {
|
||||
world.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState());
|
||||
}
|
||||
|
||||
if (state.getBlock() instanceof BlockFarmland) {
|
||||
int moisture = state.getValue(BlockFarmland.MOISTURE);
|
||||
world.setBlockState(below, state.withProperty(BlockFarmland.MOISTURE, moisture + 1));
|
||||
} else if (state.getBlock() instanceof BlockCrops) {
|
||||
int age = state.getValue(BlockCrops.AGE);
|
||||
if (age < 7) {
|
||||
world.setBlockState(below, state.withProperty(BlockCrops.AGE, age + 1), 2);
|
||||
}
|
||||
}
|
||||
|
||||
state.getBlock().fillWithRain(world, below);
|
||||
}
|
||||
}
|
||||
|
||||
if (setRainTimer(getRainTimer() - 1) == 0) {
|
||||
if (rand.nextInt(20000) == 0) {
|
||||
setDead();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rand.nextInt(8000) == 0 && canRainHere()) {
|
||||
setRaining();
|
||||
if (rand.nextInt(7000) == 0) {
|
||||
setIsThundering(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rotationPitch = 0;
|
||||
rotationYawHead = 0;
|
||||
rotationYaw = 0;
|
||||
|
||||
for (Entity i : world.getEntitiesInAABBexcluding(this, boundingbox
|
||||
.grow(1 / (1 + getCloudSize())), Predicates.ENTITY_INTERACT_WITH_CLOUDS)) {
|
||||
if (i.posY > posY + 0.5) {
|
||||
applyGravityCompensation(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBurning() && !dead) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
world.spawnParticle(EnumParticleTypes.CLOUD,
|
||||
posX + randomIn(rand, boundingbox.minX, boundingbox.maxX),
|
||||
posY + randomIn(rand, boundingbox.minY, boundingbox.maxY),
|
||||
posZ + randomIn(rand, boundingbox.minZ, boundingbox.maxZ), 0, 0.25, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (getStationary()) {
|
||||
motionX = 0;
|
||||
motionY = 0;
|
||||
motionZ = 0;
|
||||
}
|
||||
|
||||
motionX /= (1 + getCloudSize());
|
||||
motionZ /= (1 + getCloudSize());
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
hurtTime = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMountedYOffset() {
|
||||
return getEntityBoundingBox().maxY - getEntityBoundingBox().minY - 0.25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveRelative(float strafe, float up, float forward, float friction) {
|
||||
if (!getStationary()) {
|
||||
super.moveRelative(strafe, up, forward, friction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCollideWithPlayer(EntityPlayer player) {
|
||||
if (player.posY >= posY) {
|
||||
if (applyGravityCompensation(player)) {
|
||||
double difX = player.posX - player.lastTickPosX;
|
||||
double difZ = player.posZ - player.lastTickPosZ;
|
||||
double difY = player.posY - player.lastTickPosY;
|
||||
|
||||
player.distanceWalkedModified = (float)(player.distanceWalkedModified + MathHelper.sqrt(difX * difX + difZ * difZ) * 0.6);
|
||||
player.distanceWalkedOnStepModified = (float)(player.distanceWalkedOnStepModified + MathHelper.sqrt(difX * difX + difY * difY + difZ * difZ) * 0.6);
|
||||
|
||||
if (PlayerSpeciesList.instance().getPlayer(player).stepOnCloud()) {
|
||||
SoundType soundtype = SoundType.CLOTH;
|
||||
player.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch());
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onCollideWithPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateAITasks() {
|
||||
if (!getStationary()) {
|
||||
super.updateAITasks();
|
||||
if (!isBeingRidden()) {
|
||||
double diffY = altitude - posZ;
|
||||
|
||||
if (rand.nextInt(700) == 0 || diffY*diffY < 3f) {
|
||||
altitude += rand.nextInt(10) - 5;
|
||||
}
|
||||
|
||||
if (altitude > world.provider.getCloudHeight() - 8) {
|
||||
altitude = world.provider.getCloudHeight() - 18;
|
||||
} else if (altitude < 70) {
|
||||
altitude = posY + 10;
|
||||
}
|
||||
|
||||
double var3 = altitude + 0.1D - posY;
|
||||
motionX -= 0.001;
|
||||
motionY += (Math.signum(var3) * 0.699999988079071D - motionY) * 0.10000000149011612D;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
|
||||
if (!(isBeingRidden() || isRidingOrBeingRiddenBy(player)) && hand == EnumHand.MAIN_HAND) {
|
||||
if (Predicates.INTERACT_WITH_CLOUDS.test(player)) {
|
||||
|
||||
if (player.getItemInUseCount() > 0) {
|
||||
return EnumActionResult.FAIL;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
|
||||
if (stack != null) {
|
||||
if (stack.getItem() instanceof ItemBlock || stack.getItem() == Items.SPAWN_EGG && stack.getItemDamage() == EntityList.getID(EntityCloud.class)) {
|
||||
placeBlock(player, stack, hand);
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (!getStationary()) {
|
||||
player.startRiding(this);
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return EnumActionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStatusUpdate(byte type) {
|
||||
if (type == 2) {
|
||||
if (!isBurning()) {
|
||||
for (int i = 0; i < 50 * getCloudSize(); i++) {
|
||||
Particles.instance().getEntityEmitter().emitDiggingParticles(this, UBlocks.cloud.getDefaultState());
|
||||
}
|
||||
}
|
||||
}
|
||||
super.handleStatusUpdate(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
Entity attacker = source.getImmediateSource();
|
||||
|
||||
if (attacker instanceof EntityPlayer) {
|
||||
return onAttackByPlayer(source, amount, (EntityPlayer)attacker);
|
||||
}
|
||||
|
||||
return source == DamageSource.IN_WALL || super.attackEntityFrom(source, amount);
|
||||
}
|
||||
|
||||
private void placeBlock(EntityPlayer player, ItemStack stack, EnumHand hand) {
|
||||
if (!world.isRemote || !(player instanceof EntityPlayerSP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
double distance = mc.playerController.getBlockReachDistance();
|
||||
|
||||
float ticks = mc.getRenderPartialTicks();
|
||||
|
||||
Vec3d eye = player.getPositionEyes(ticks);
|
||||
Vec3d look = player.getLook(ticks);
|
||||
Vec3d ray = eye.add(look.x * distance, look.y * distance, look.z * distance);
|
||||
|
||||
AxisAlignedBB bounds = getEntityBoundingBox();
|
||||
|
||||
float s = 0.5F;
|
||||
RayTraceResult trace = bounds
|
||||
.contract(0, s, 0).contract(0, -s, 0)
|
||||
.calculateIntercept(eye, ray);
|
||||
|
||||
if (trace == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setStationary(true);
|
||||
|
||||
EnumFacing direction = trace.sideHit;
|
||||
|
||||
BlockPos blockPos = new BlockPos(trace.hitVec);
|
||||
|
||||
mc.objectMouseOver = new RayTraceResult(trace.hitVec, direction, blockPos);
|
||||
|
||||
int oldCount = stack.getCount();
|
||||
EnumActionResult result = mc.playerController.processRightClickBlock(((EntityPlayerSP)player), (WorldClient)player.world, blockPos, direction, trace.hitVec, hand);
|
||||
|
||||
if (result == EnumActionResult.SUCCESS) {
|
||||
player.swingArm(hand);
|
||||
|
||||
if (!stack.isEmpty() && (stack.getCount() != oldCount || mc.playerController.isInCreativeMode())) {
|
||||
mc.entityRenderer.itemRenderer.resetEquippedProgress(hand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onAttackByPlayer(DamageSource source, float amount, EntityPlayer player) {
|
||||
boolean canFly = PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds();
|
||||
boolean stat = getStationary();
|
||||
|
||||
if (stat || canFly) {
|
||||
if (!isBurning()) {
|
||||
for (int i = 0; i < 50 * getCloudSize(); i++) {
|
||||
Particles.instance().getEntityEmitter().emitDiggingParticles(this, UBlocks.cloud.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
if (stack != null && stack.getItem() instanceof ItemSword) {
|
||||
return super.attackEntityFrom(source, amount);
|
||||
} else if (stack != null && stack.getItem() instanceof ItemSpade) {
|
||||
return super.attackEntityFrom(source, amount * 1.5f);
|
||||
} else if (canFly) {
|
||||
if (player.posY < posY) {
|
||||
altitude += 5;
|
||||
} else if (player.posY > posY) {
|
||||
altitude -= 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeath(DamageSource s) {
|
||||
if (s == DamageSource.GENERIC || (s.getTrueSource() != null && s.getTrueSource() instanceof EntityPlayer)) {
|
||||
if (!isBurning()) {
|
||||
Particles.instance().getEntityEmitter().emitDestructionParticles(this, UBlocks.cloud.getDefaultState());
|
||||
}
|
||||
|
||||
setDead();
|
||||
}
|
||||
super.onDeath(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropFewItems(boolean hitByPlayer, int looting) {
|
||||
if (hitByPlayer) {
|
||||
Item item = getDropItem();
|
||||
int amount = 2 + world.rand.nextInt(3 + looting);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
dropItem(item, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound tag) {
|
||||
super.readEntityFromNBT(tag);
|
||||
|
||||
setRainTimer(tag.getInteger("RainTimer"));
|
||||
setIsThundering(tag.getBoolean("IsThundering"));
|
||||
setCloudSize(tag.getByte("CloudSize"));
|
||||
setStationary(tag.getBoolean("IsStationary"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound tag) {
|
||||
super.writeEntityToNBT(tag);
|
||||
|
||||
tag.setInteger("RainTimer", getRainTimer());
|
||||
tag.setBoolean("IsThundering", getIsThundering());
|
||||
tag.setByte("CloudSize", (byte)getCloudSize());
|
||||
tag.setBoolean("IsStationary", getStationary());
|
||||
}
|
||||
|
||||
protected boolean applyGravityCompensation(Entity entity) {
|
||||
int floatStrength = getFloatStrength(entity);
|
||||
|
||||
if (!isRidingOrBeingRiddenBy(entity) && floatStrength > 0) {
|
||||
|
||||
double boundModifier = entity.fallDistance > 80 ? 80 : MathHelper.floor(entity.fallDistance * 10) / 10;
|
||||
|
||||
entity.onGround = true;
|
||||
entity.motionY += (((floatStrength > 2 ? 1 : floatStrength/2) * 0.699999998079071D) - entity.motionY + boundModifier * 0.7) * 0.10000000149011612D;
|
||||
|
||||
if (!getStationary() && entity.motionY > 0.4 && world.rand.nextInt(900) == 0) {
|
||||
spawnThunderbolt(getPosition());
|
||||
}
|
||||
|
||||
if (entity instanceof EntityItem) {
|
||||
entity.motionX /= 8;
|
||||
entity.motionZ /= 8;
|
||||
entity.motionY /= 16;
|
||||
entity.setNoGravity(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getFloatStrength(Entity entity) {
|
||||
if (Predicates.ENTITY_INTERACT_WITH_CLOUDS.test(entity)) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (entity instanceof EntityPlayer) {
|
||||
return getFeatherEnchantStrength((EntityPlayer)entity);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getFeatherEnchantStrength(EntityPlayer player) {
|
||||
for (ItemStack stack : player.getArmorInventoryList()) {
|
||||
if (stack != null) {
|
||||
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
|
||||
if (enchantments.containsKey(Enchantments.FEATHER_FALLING)) {
|
||||
return (Integer)enchantments.get(Enchantments.FEATHER_FALLING);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private boolean canRainHere() {
|
||||
return world.getBiome(new BlockPos(posX, posY, posZ)).canRain();
|
||||
}
|
||||
|
||||
private boolean canSnowHere(BlockPos pos) {
|
||||
return world.getBiome(pos).getTemperature(pos) <= 0.15f;
|
||||
}
|
||||
|
||||
public void spawnThunderbolt() {
|
||||
spawnThunderbolt(getGroundPosition(posX, posZ));
|
||||
}
|
||||
|
||||
public void spawnThunderbolt(BlockPos pos) {
|
||||
world.addWeatherEffect(new EntityLightningBolt(world, pos.getX(), pos.getY(), pos.getZ(), false));
|
||||
}
|
||||
|
||||
private BlockPos getGroundPosition(double x, double z) {
|
||||
BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(x, posY, z));
|
||||
|
||||
if (pos.getY() >= posY) {
|
||||
while (world.isValid(pos)) {
|
||||
pos = pos.down();
|
||||
if (world.getBlockState(pos).isSideSolid(world, pos, EnumFacing.UP)) {
|
||||
return pos.up();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int getRainTimer() {
|
||||
return dataManager.get(RAINTIMER);
|
||||
}
|
||||
|
||||
public int setRainTimer(int val) {
|
||||
if (val < 0) val = 0;
|
||||
dataManager.set(RAINTIMER, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
private void setRaining() {
|
||||
setRainTimer(700 + rand.nextInt(20));
|
||||
}
|
||||
|
||||
public void setIsRaining(boolean val) {
|
||||
if (val) {
|
||||
setRaining();
|
||||
} else {
|
||||
setRainTimer(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getIsRaining() {
|
||||
return getRainTimer() > 0;
|
||||
}
|
||||
|
||||
public boolean getIsThundering() {
|
||||
return dataManager.get(THUNDERING);
|
||||
}
|
||||
|
||||
public void setIsThundering(boolean val) {
|
||||
dataManager.set(THUNDERING, val);
|
||||
}
|
||||
|
||||
public boolean getStationary() {
|
||||
return dataManager.get(STATIONARY);
|
||||
}
|
||||
|
||||
public void setStationary(boolean val) {
|
||||
dataManager.set(STATIONARY, val);
|
||||
}
|
||||
|
||||
public boolean getOpaque() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getCloudSize() {
|
||||
int size = dataManager.get(SCALE);
|
||||
updateSize(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
private void updateSize(int scale) {
|
||||
setSize((float)baseWidth * scale, (float)baseHeight * scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSize(float width, float height) {
|
||||
if (width != this.width || height != this.height) {
|
||||
super.setSize(width, height);
|
||||
setPosition(posX, posY, posZ);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCloudSize(int val) {
|
||||
val = Math.min(1, val);
|
||||
updateSize(val);
|
||||
dataManager.set(SCALE, val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityConstructionCloud extends EntityCloud {
|
||||
|
||||
public EntityConstructionCloud(World world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getStationary() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOpaque() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityRacingCloud extends EntityCloud {
|
||||
|
||||
public EntityRacingCloud(World world) {
|
||||
super(world);
|
||||
setCloudSize(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeSteered() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canFitPassenger(Entity passenger) {
|
||||
return getPassengers().size() < getCloudSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Entity getControllingPassenger() {
|
||||
List<Entity> list = getPassengers();
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
Entity riddenByEntity = getControllingPassenger();
|
||||
|
||||
if (riddenByEntity != null && canPassengerSteer()) {
|
||||
EntityLivingBase rider = (EntityLivingBase)riddenByEntity;
|
||||
|
||||
double speed = 1.5F * rider.moveForward / 5;
|
||||
double horizontalDriving = (riddenByEntity.rotationYaw - rider.moveStrafing * 90) * Math.PI / 180;
|
||||
|
||||
motionX += -Math.sin(horizontalDriving) * speed;
|
||||
motionZ += Math.cos(horizontalDriving) * speed;
|
||||
|
||||
double pitch = riddenByEntity.rotationPitch * Math.PI / 180;
|
||||
|
||||
motionY += -Math.sin(pitch) * (speed / 20);
|
||||
} else {
|
||||
motionY = 0;
|
||||
}
|
||||
|
||||
super.onUpdate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.IEntityLivingData;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityWildCloud extends EntityCloud {
|
||||
|
||||
public EntityWildCloud(World world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotColliding() {
|
||||
AxisAlignedBB boundingbox = getEntityBoundingBox();
|
||||
return checkNoEntityCollision(boundingbox, this) && world.getCollisionBoxes(this, boundingbox).isEmpty() && !world.containsAnyLiquid(boundingbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are no solid, live entities in the specified AxisAlignedBB, excluding the given entity
|
||||
*
|
||||
* @ref World.checkNoEntityCollision(AxisAlignedBB area, Entity entity)
|
||||
*/
|
||||
public boolean checkNoEntityCollision(AxisAlignedBB area, Entity entity) {
|
||||
List<Entity> list = world.getEntitiesWithinAABBExcludingEntity(null, area);
|
||||
for (Entity i : list) {
|
||||
if (!i.isDead && (i.preventEntitySpawning || i instanceof EntityCloud) && i != entity && (!entity.isRiding() || !entity.isRidingOrBeingRiddenBy(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) {
|
||||
checkLocation();
|
||||
return super.onInitialSpawn(difficulty, livingdata);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.CloudSize;
|
||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.util.math.RayTraceResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ItemCloud extends Item {
|
||||
|
||||
public ItemCloud(String domain, String name) {
|
||||
super();
|
||||
setHasSubtypes(true);
|
||||
setMaxDamage(0);
|
||||
setTranslationKey(name);
|
||||
setRegistryName(domain, name);
|
||||
setCreativeTab(CreativeTabs.MATERIALS);
|
||||
|
||||
maxStackSize = 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
|
||||
if (!world.isRemote) {
|
||||
RayTraceResult mop = rayTrace(world, player, true);
|
||||
|
||||
BlockPos pos;
|
||||
|
||||
if (mop != null && mop.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
pos = mop.getBlockPos().offset(mop.sideHit);
|
||||
} else {
|
||||
pos = player.getPosition();
|
||||
}
|
||||
|
||||
EntityCloud cloud = CloudSize.byMetadata(stack.getItemDamage()).createEntity(world);
|
||||
cloud.moveToBlockPosAndAngles(pos, 0, 0);
|
||||
world.spawnEntity(cloud);
|
||||
|
||||
if (!player.capabilities.isCreativeMode) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
}
|
||||
|
||||
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(ItemStack stack) {
|
||||
return super.getTranslationKey(stack) + "." + CloudSize.byMetadata(stack.getItemDamage()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subs) {
|
||||
if (isInCreativeTab(tab)) {
|
||||
for (CloudSize i : CloudSize.values()) {
|
||||
subs.add(new ItemStack(this, 1, i.getMetadata()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class UItemBlock extends ItemBlock {
|
||||
|
||||
private final Predicate<EntityPlayer> abilityTest;
|
||||
|
||||
public UItemBlock(Block block, Predicate<EntityPlayer> abilityTest) {
|
||||
super(block);
|
||||
|
||||
this.abilityTest = abilityTest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) {
|
||||
if (!abilityTest.test(player)) {
|
||||
return player.capabilities.isCreativeMode;
|
||||
}
|
||||
|
||||
return super.canPlaceBlockOnSide(worldIn, pos, side, player, stack);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemMultiTexture;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class UItemMultiTexture extends ItemMultiTexture {
|
||||
|
||||
private final Predicate<EntityPlayer> abilityTest;
|
||||
|
||||
public UItemMultiTexture(Block block, ItemMultiTexture.Mapper mapper, Predicate<EntityPlayer> abilityTest) {
|
||||
super(block, block, mapper);
|
||||
|
||||
this.abilityTest = abilityTest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) {
|
||||
if (!abilityTest.test(player)) {
|
||||
return player.capabilities.isCreativeMode;
|
||||
}
|
||||
|
||||
return super.canPlaceBlockOnSide(worldIn, pos, side, player, stack);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemSlab;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class UItemSlab extends ItemSlab {
|
||||
|
||||
private final Predicate<EntityPlayer> abilityTest;
|
||||
|
||||
public UItemSlab(Block block, BlockSlab singleSlab, BlockSlab doubleSlab, Predicate<EntityPlayer> abilityTest) {
|
||||
super(block, singleSlab, doubleSlab);
|
||||
|
||||
this.abilityTest = abilityTest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) {
|
||||
if (!abilityTest.test(player)) {
|
||||
return player.capabilities.isCreativeMode;
|
||||
}
|
||||
|
||||
return super.canPlaceBlockOnSide(worldIn, pos, side, player, stack);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.minelittlepony.unicopia.model;
|
||||
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public class ModelCloud extends ModelBase {
|
||||
ModelRenderer body;
|
||||
|
||||
public ModelCloud() {
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
body = new ModelRenderer(this, 0, 0);
|
||||
|
||||
body.addBox(-24, 5, -24, 48, 10, 48);
|
||||
|
||||
body.addBox(-10, 14.999F, -10, 30, 2, 30);
|
||||
body.addBox(-19.999F, 14.999F, -15, 15, 3, 25);
|
||||
|
||||
body.addBox(-10, 3.001F, -10, 30, 2, 30);
|
||||
body.rotationPointY += 4.2;
|
||||
}
|
||||
|
||||
public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||
body.render(scale);
|
||||
}
|
||||
}
|
11
src/main/java/com/minelittlepony/unicopia/player/IOwned.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
public interface IOwned<E> {
|
||||
|
||||
default void setOwner(E owner) {
|
||||
|
||||
}
|
||||
|
||||
E getOwner();
|
||||
|
||||
}
|
|
@ -2,18 +2,13 @@ package com.minelittlepony.unicopia.player;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.InbtSerialisable;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
public interface IPlayer extends ICaster<EntityPlayer>, InbtSerialisable, IUpdatable {
|
||||
Race getPlayerSpecies();
|
||||
|
||||
void setPlayerSpecies(Race race);
|
||||
public interface IPlayer extends ICaster<EntityPlayer>, IRaceContainer<EntityPlayer> {
|
||||
|
||||
void sendCapabilities(boolean full);
|
||||
|
||||
|
@ -33,6 +28,8 @@ public interface IPlayer extends ICaster<EntityPlayer>, InbtSerialisable, IUpdat
|
|||
|
||||
void onEntityEat();
|
||||
|
||||
boolean stepOnCloud();
|
||||
|
||||
void onFall(float distance, float damageMultiplier);
|
||||
|
||||
static EntityPlayer getPlayerEntity(UUID playerId) {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
import com.minelittlepony.unicopia.InbtSerialisable;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface IRaceContainer<T extends Entity> extends InbtSerialisable, IUpdatable<T> {
|
||||
Race getPlayerSpecies();
|
||||
|
||||
void setPlayerSpecies(Race race);
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface IUpdatable {
|
||||
void onUpdate(EntityPlayer entity);
|
||||
public interface IUpdatable<T extends Entity> {
|
||||
void onUpdate(T entity);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
class ItemCapabilities implements IRaceContainer<EntityItem>, IOwned<EntityItem> {
|
||||
|
||||
private Race race = Race.HUMAN;
|
||||
|
||||
private EntityItem owner;
|
||||
|
||||
@Override
|
||||
public void onUpdate(EntityItem entity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Race getPlayerSpecies() {
|
||||
return race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerSpecies(Race race) {
|
||||
this.race = race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound compound) {
|
||||
compound.setString("owner_species", race.name());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
race = Race.fromName(compound.getString("owner_species"), Race.HUMAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(EntityItem owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityItem getOwner() {
|
||||
return owner;
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import com.minelittlepony.unicopia.power.PowersRegistry;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable, InbtSerialisable {
|
||||
class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable<EntityPlayer>, InbtSerialisable {
|
||||
|
||||
private final IPlayer player;
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.entity.ai.attributes.IAttribute;
|
||||
import net.minecraft.entity.ai.attributes.IAttributeInstance;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
class PlayerAttributes {
|
||||
public static final int ADD = 0;
|
||||
public static final int ADD_PERCENTAGE = 1;
|
||||
public static final int MULTIPLY = 2;
|
||||
|
||||
public static final PlayerAttributes instance = new PlayerAttributes();
|
||||
|
||||
private final AttributeModifier EARTH_PONY_STRENGTH =
|
||||
new AttributeModifier(UUID.fromString("777a5505-521e-480b-b9d5-6ea54f259564"), "Earth Pony Strength", 0.6, MULTIPLY);
|
||||
|
||||
private final AttributeModifier PEGASUS_SPEED =
|
||||
new AttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7"), "Pegasus Speed", 0.2, MULTIPLY);
|
||||
|
||||
private final AttributeModifier PEGASUS_REACH =
|
||||
new AttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, ADD);
|
||||
|
||||
public void applyAttributes(EntityPlayer entity, Race race) {
|
||||
applyAttribute(entity, SharedMonsterAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
applyAttribute(entity, SharedMonsterAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
applyAttribute(entity, SharedMonsterAttributes.MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
applyAttribute(entity, SharedMonsterAttributes.ATTACK_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
applyAttribute(entity, EntityPlayer.REACH_DISTANCE, PEGASUS_REACH, race.canFly());
|
||||
}
|
||||
|
||||
private void applyAttribute(EntityPlayer entity, IAttribute attribute, AttributeModifier modifier, boolean enable) {
|
||||
IAttributeInstance instance = entity.getEntityAttribute(attribute);
|
||||
|
||||
if (enable) {
|
||||
if (instance.getModifier(modifier.getID()) == null) {
|
||||
instance.applyModifier(modifier);
|
||||
}
|
||||
} else {
|
||||
if (instance.getModifier(modifier.getID()) != null) {
|
||||
instance.removeModifier(modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
|
||||
private final PlayerGravityDelegate gravity = new PlayerGravityDelegate(this);
|
||||
|
||||
private float nextStepDistance = 1;
|
||||
|
||||
private IMagicEffect effect;
|
||||
|
||||
private EntityPlayer entity;
|
||||
|
@ -61,7 +63,7 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
public void setPlayerSpecies(Race race) {
|
||||
EntityPlayer self = getOwner();
|
||||
|
||||
if (!PlayerSpeciesList.instance().speciesPermitted(race)) {
|
||||
if (!PlayerSpeciesList.instance().speciesPermitted(race, getOwner())) {
|
||||
race = Race.HUMAN;
|
||||
}
|
||||
|
||||
|
@ -128,6 +130,8 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
}
|
||||
|
||||
addExertion(-1);
|
||||
|
||||
PlayerAttributes.instance.applyAttributes(entity, getPlayerSpecies());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,6 +147,22 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean stepOnCloud() {
|
||||
EntityPlayer player = getOwner();
|
||||
|
||||
if ((player.fallDistance > 1) || player.distanceWalkedOnStepModified > nextStepDistance) {
|
||||
nextStepDistance = player.distanceWalkedOnStepModified + 2;
|
||||
player.fallDistance = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityEat() {
|
||||
if (getPlayerSpecies() == Race.CHANGELING) {
|
||||
EntityPlayer player = getOwner();
|
||||
|
@ -166,7 +186,7 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
setPlayerSpecies(Race.fromName(compound.getString("playerSpecies")));
|
||||
setPlayerSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
|
||||
powers.readFromNBT(compound.getCompoundTag("powers"));
|
||||
gravity.readFromNBT(compound.getCompoundTag("gravity"));
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.util.SoundEvent;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
class PlayerGravityDelegate implements IUpdatable, InbtSerialisable {
|
||||
class PlayerGravityDelegate implements IUpdatable<EntityPlayer>, InbtSerialisable {
|
||||
|
||||
private final IPlayer player;
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.UUID;
|
|||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import come.minelittlepony.unicopia.forgebullshit.FBS;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public class PlayerSpeciesList {
|
||||
|
@ -19,12 +21,24 @@ public class PlayerSpeciesList {
|
|||
|
||||
private List<Race> serverPermittedRaces = new ArrayList<>();
|
||||
|
||||
public boolean speciesPermitted(Race race) {
|
||||
public boolean speciesPermitted(Race race, EntityPlayer sender) {
|
||||
if (race == Race.ALICORN && (sender == null || !sender.capabilities.isCreativeMode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return race.isDefault() || serverPermittedRaces.isEmpty() || serverPermittedRaces.contains(race);
|
||||
}
|
||||
|
||||
public IPlayer emptyPlayer(EntityPlayer player) {
|
||||
return new PlayerCapabilities(player);
|
||||
public IRaceContainer<?> emptyContainer(Entity entity) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
return new PlayerCapabilities((EntityPlayer)entity);
|
||||
}
|
||||
|
||||
if (entity instanceof EntityItem) {
|
||||
return new ItemCapabilities();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("entity");
|
||||
}
|
||||
|
||||
public IPlayer getPlayer(EntityPlayer player) {
|
||||
|
@ -34,4 +48,8 @@ public class PlayerSpeciesList {
|
|||
public IPlayer getPlayer(UUID playerId) {
|
||||
return getPlayer(IPlayer.getPlayerEntity(playerId));
|
||||
}
|
||||
|
||||
public <T extends Entity> IRaceContainer<T> getEntity(T entity) {
|
||||
return FBS.of(entity).getRaceContainer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.minelittlepony.unicopia.power;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
@ -78,10 +77,7 @@ public class PowerFeed implements IPower<Hit> {
|
|||
|
||||
@Override
|
||||
public void apply(EntityPlayer player, Hit data) {
|
||||
List<Entity> list = new ArrayList<Entity>();
|
||||
for (Entity i : VecHelper.getWithinRange(player, 3)) {
|
||||
if (canDrain(i)) list.add(i);
|
||||
}
|
||||
List<Entity> list = VecHelper.getWithinRange(player, 3, this::canDrain);
|
||||
|
||||
Entity looked = VecHelper.getLookedAtEntity(player, 10);
|
||||
if (looked != null && !list.contains(looked)) {
|
||||
|
@ -97,8 +93,7 @@ public class PowerFeed implements IPower<Hit> {
|
|||
for (Entity i : list) {
|
||||
DamageSource d = MagicalDamageSource.causePlayerDamage("feed", player);
|
||||
|
||||
if (EnumCreatureType.CREATURE.getCreatureClass().isAssignableFrom(i.getClass())
|
||||
|| player.world.rand.nextFloat() > 0.95f) {
|
||||
if (EnumCreatureType.CREATURE.getCreatureClass().isAssignableFrom(i.getClass()) || player.world.rand.nextFloat() > 0.95f) {
|
||||
i.attackEntityFrom(d, Integer.MAX_VALUE);
|
||||
} else {
|
||||
i.attackEntityFrom(d, drained);
|
||||
|
|
|
@ -143,7 +143,7 @@ public class PowerTeleport implements IPower<Location> {
|
|||
|
||||
@Override
|
||||
public void preApply(IPlayer player) {
|
||||
player.addExertion(1);
|
||||
player.addExertion(3);
|
||||
|
||||
IPower.spawnParticles(Unicopia.MAGIC_PARTICLE, player, 5);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package com.minelittlepony.unicopia.render;
|
||||
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||
import com.minelittlepony.unicopia.model.ModelCloud;
|
||||
|
||||
public class RenderCloud extends RenderLiving<EntityCloud> {
|
||||
private static final ResourceLocation cloud = new ResourceLocation("unicopia", "textures/entity/clouds.png");
|
||||
private static final ResourceLocation rainCloud = new ResourceLocation("unicopia", "textures/entity/clouds_storm.png");
|
||||
|
||||
public RenderCloud(RenderManager rendermanagerIn) {
|
||||
super(rendermanagerIn, new ModelCloud(), 1f);
|
||||
}
|
||||
|
||||
public float prepareScale(EntityCloud entity, float par2) {
|
||||
float scale = entity.getCloudSize();
|
||||
|
||||
GL11.glScalef(scale, scale, scale);
|
||||
return 0.0625F;
|
||||
}
|
||||
|
||||
protected void renderModel(EntityCloud entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor) {
|
||||
|
||||
if (!entity.isDead) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0, -entity.height/2, 0);
|
||||
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
|
||||
if (!((EntityCloud)entity).getOpaque()) {
|
||||
GL11.glColor4f(1, 1, 1, 0.8F);
|
||||
}
|
||||
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
super.renderModel(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor);
|
||||
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
protected ResourceLocation getEntityTexture(EntityCloud entity) {
|
||||
if (entity.getIsRaining() && entity.getIsThundering()) {
|
||||
return rainCloud;
|
||||
}
|
||||
return cloud;
|
||||
}
|
||||
|
||||
protected int getColorMultiplier(EntityCloud par1EntityLivingBase, float yaw, float pitch) {
|
||||
return 25;
|
||||
}
|
||||
|
||||
protected float getDeathMaxRotation(EntityCloud par1EntityLivingBase) {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package com.minelittlepony.unicopia.spell;
|
||||
|
||||
import com.minelittlepony.unicopia.player.IOwned;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
public interface ICaster<E extends EntityLivingBase> {
|
||||
public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
|
||||
void setEffect(IMagicEffect effect);
|
||||
|
||||
IMagicEffect getEffect();
|
||||
|
@ -12,12 +14,6 @@ public interface ICaster<E extends EntityLivingBase> {
|
|||
return getEffect() != null;
|
||||
}
|
||||
|
||||
default void setOwner(E owner) {
|
||||
|
||||
}
|
||||
|
||||
E getOwner();
|
||||
|
||||
default Entity getEntity() {
|
||||
return getOwner();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.minelittlepony.util.vector;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -23,11 +25,11 @@ public class VecHelper {
|
|||
*
|
||||
* @return RayTraceResult result or null
|
||||
*/
|
||||
public static RayTraceResult rayTrace(Entity e, double distance, float partialTick) {
|
||||
Vec3d pos = geteEyePosition(e, partialTick);
|
||||
Vec3d look = e.getLook(partialTick);
|
||||
Vec3d ray = pos.add(look.x * distance, look.y * distance, look.z * distance);
|
||||
return e.world.rayTraceBlocks(pos, ray, false, false, true);
|
||||
public static RayTraceResult rayTrace(Entity e, double distance, float partialTicks) {
|
||||
Vec3d pos = e.getPositionEyes(partialTicks);
|
||||
Vec3d look = e.getLook(partialTicks).scale(distance);
|
||||
|
||||
return e.world.rayTraceBlocks(pos, pos.add(look), false, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,28 +48,14 @@ public class VecHelper {
|
|||
/**
|
||||
* Gets all entities within a given range from the player.
|
||||
*/
|
||||
public static List<Entity> getWithinRange(EntityPlayer player, double reach) {
|
||||
Vec3d look = player.getLook(0);
|
||||
float var9 = 1.0F;
|
||||
return player.world.getEntitiesWithinAABBExcludingEntity(player, player.getEntityBoundingBox().expand(look.x * reach, look.y * reach, look.z * reach).expand((double)var9, (double)var9, (double)var9));
|
||||
}
|
||||
public static List<Entity> getWithinRange(EntityPlayer player, double reach, @Nullable Predicate <? super Entity > predicate) {
|
||||
Vec3d look = player.getLook(0).scale(reach);
|
||||
|
||||
/**
|
||||
* Gets the position vector of an entity's eyes for ray tracing.
|
||||
*
|
||||
* @param e Entity
|
||||
* @param partialTick Client partial ticks
|
||||
*
|
||||
* @return A vector of the entity's eye position
|
||||
*/
|
||||
public static Vec3d geteEyePosition(Entity e, float partialTick) {
|
||||
double eyeHeight = e.getEyeHeight();
|
||||
if (partialTick == 1) return new Vec3d(e.posX, e.posY + eyeHeight, e.posZ);
|
||||
double x = e.prevPosX + (e.posX - e.prevPosX) * partialTick;
|
||||
double y = e.prevPosY + (e.posY - e.prevPosY) * partialTick + eyeHeight;
|
||||
double z = e.prevPosZ + (e.posZ - e.prevPosZ) * partialTick;
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
return player.world.getEntitiesInAABBexcluding(player, player
|
||||
.getEntityBoundingBox()
|
||||
.expand(look.x, look.y, look.z)
|
||||
.expand(1, 1, 1), predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a ray trace from the given entity and returns a result for the first Entity or block that the ray intercepts.
|
||||
|
@ -79,7 +67,7 @@ public class VecHelper {
|
|||
* @return RayTraceResult result or null
|
||||
*/
|
||||
public static RayTraceResult getObjectMouseOver(Entity e, double distance, float partialTick) {
|
||||
return getObjectMouseOverExcept(e, distance, partialTick, EntitySelectors.NOT_SPECTATING);
|
||||
return getObjectMouseOver(e, distance, partialTick, EntitySelectors.NOT_SPECTATING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,23 +82,28 @@ public class VecHelper {
|
|||
*
|
||||
* @return RayTraceResult result or null
|
||||
*/
|
||||
public static RayTraceResult getObjectMouseOverExcept(Entity e, double distance, float partialTick, Predicate<Entity> predicate) {
|
||||
public static RayTraceResult getObjectMouseOver(Entity e, double distance, float partialTick, Predicate<Entity> predicate) {
|
||||
RayTraceResult tracedBlock = rayTrace(e, distance, partialTick);
|
||||
|
||||
double totalTraceDistance = distance;
|
||||
|
||||
Vec3d pos = geteEyePosition(e, partialTick);
|
||||
Vec3d pos = e.getPositionEyes(partialTick);
|
||||
|
||||
if (tracedBlock != null) totalTraceDistance = tracedBlock.hitVec.distanceTo(pos);
|
||||
if (tracedBlock != null) {
|
||||
totalTraceDistance = tracedBlock.hitVec.distanceTo(pos);
|
||||
}
|
||||
|
||||
Vec3d look = e.getLook(partialTick);
|
||||
Vec3d ray = pos.add(look.x * distance, look.y * distance, look.z * distance);
|
||||
Vec3d ray = pos.add(look.scale(distance));
|
||||
|
||||
Vec3d hit = null;
|
||||
Entity pointedEntity = null;
|
||||
List<Entity> entitiesWithinRange = e.world.getEntitiesInAABBexcluding(e, e.getEntityBoundingBox().grow(look.x * distance, look.y * distance, look.z * distance).expand(1, 1, 1), predicate);
|
||||
List<Entity> entitiesWithinRange = e.world.getEntitiesInAABBexcluding(e, e.getEntityBoundingBox()
|
||||
.grow(look.x * distance, look.y * distance, look.z * distance)
|
||||
.expand(1, 1, 1), predicate);
|
||||
|
||||
double traceDistance = totalTraceDistance;
|
||||
|
||||
for (Entity entity : entitiesWithinRange) {
|
||||
if (entity.canBeCollidedWith()) {
|
||||
double size = entity.getCollisionBorderSize();
|
||||
|
@ -144,6 +137,7 @@ public class VecHelper {
|
|||
if (pointedEntity != null && (traceDistance < totalTraceDistance || tracedBlock == null)) {
|
||||
return new RayTraceResult(pointedEntity, hit);
|
||||
}
|
||||
|
||||
return tracedBlock;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import com.minelittlepony.unicopia.player.IOwned;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.IRaceContainer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||
|
||||
class DefaultEntityCapabilitiesProxyContainer<T extends Entity> implements ICapabilitiesProxyContainer<T> {
|
||||
|
||||
@CapabilityInject(ICapabilitiesProxyContainer.class)
|
||||
public static final Capability<ICapabilitiesProxyContainer<?>> CAPABILITY = null;
|
||||
|
||||
private IRaceContainer<T> container;
|
||||
|
||||
|
||||
@Override
|
||||
public IRaceContainer<T> getRaceContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayer getPlayer() {
|
||||
return (IPlayer)container;
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound compound) {
|
||||
container.writeToNBT(compound);
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
container.readFromNBT(compound);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ICapabilitiesProxyContainer<T> withEntity(T entity) {
|
||||
if (this.container == null) {
|
||||
this.container = (IRaceContainer<T>)PlayerSpeciesList.instance().emptyContainer(entity);
|
||||
} else if (container instanceof IOwned<?>) {
|
||||
((IOwned<T>)container).setOwner(entity);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||
|
||||
class DefaultPlayerCapabilitiesProxyContainer implements IPlayerCapabilitiesProxyContainer {
|
||||
|
||||
@CapabilityInject(IPlayerCapabilitiesProxyContainer.class)
|
||||
public static final Capability<IPlayerCapabilitiesProxyContainer> CAPABILITY = null;
|
||||
|
||||
private IPlayer player;
|
||||
|
||||
@Override
|
||||
public IPlayer getPlayer() {
|
||||
if (player == null) {
|
||||
player = PlayerSpeciesList.instance().emptyPlayer(null);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayer(IPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound compound) {
|
||||
getPlayer().writeToNBT(compound);
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
getPlayer().readFromNBT(compound);
|
||||
}
|
||||
|
||||
public IPlayerCapabilitiesProxyContainer withEntity(EntityPlayer player) {
|
||||
if (this.player == null) {
|
||||
this.player = PlayerSpeciesList.instance().emptyPlayer(player);
|
||||
} else {
|
||||
getPlayer().setOwner(player);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -10,32 +11,37 @@ import net.minecraftforge.event.entity.player.PlayerEvent;
|
|||
|
||||
public class FBS {
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static void init() {
|
||||
CapabilityManager.INSTANCE.register(IPlayerCapabilitiesProxyContainer.class,
|
||||
new Storage(), DefaultPlayerCapabilitiesProxyContainer::new);
|
||||
CapabilityManager.INSTANCE.register(ICapabilitiesProxyContainer.class,
|
||||
new Storage(), DefaultEntityCapabilitiesProxyContainer::new);
|
||||
}
|
||||
|
||||
public static void attach(AttachCapabilitiesEvent<Entity> event) {
|
||||
if (event.getObject() instanceof EntityPlayer) {
|
||||
event.addCapability(new ResourceLocation("unicopia", "race"), new Provider((EntityPlayer)event.getObject()));
|
||||
if (event.getObject() instanceof EntityPlayer
|
||||
|| event.getObject() instanceof EntityItem) {
|
||||
event.addCapability(new ResourceLocation("unicopia", "race"), new Provider(event.getObject()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void clone(PlayerEvent.Clone event) {
|
||||
final IPlayerCapabilitiesProxyContainer original = of(event.getOriginal());
|
||||
final ICapabilitiesProxyContainer<EntityPlayer> original = of(event.getOriginal());
|
||||
|
||||
if (original == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final IPlayerCapabilitiesProxyContainer clone = of(event.getEntity());
|
||||
final ICapabilitiesProxyContainer<EntityPlayer> clone = of((EntityPlayer)event.getEntity());
|
||||
|
||||
clone.getPlayer().copyFrom(original.getPlayer());
|
||||
}
|
||||
|
||||
public static IPlayerCapabilitiesProxyContainer of(Entity entity) {
|
||||
if (entity.hasCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN)) {
|
||||
return entity.getCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN).withEntity((EntityPlayer)entity);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Entity> ICapabilitiesProxyContainer<T> of(T entity) {
|
||||
if (entity.hasCapability(DefaultEntityCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN)) {
|
||||
return ((ICapabilitiesProxyContainer<T>)entity
|
||||
.getCapability(DefaultEntityCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN))
|
||||
.withEntity(entity);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import com.minelittlepony.unicopia.InbtSerialisable;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.IRaceContainer;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface ICapabilitiesProxyContainer<T extends Entity> extends InbtSerialisable {
|
||||
IPlayer getPlayer();
|
||||
|
||||
IRaceContainer<T> getRaceContainer();
|
||||
|
||||
ICapabilitiesProxyContainer<T> withEntity(T entity);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import com.minelittlepony.unicopia.InbtSerialisable;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public interface IPlayerCapabilitiesProxyContainer extends InbtSerialisable {
|
||||
IPlayer getPlayer();
|
||||
|
||||
void setPlayer(IPlayer player);
|
||||
|
||||
IPlayerCapabilitiesProxyContainer withEntity(EntityPlayer player);
|
||||
}
|
|
@ -1,29 +1,30 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||
|
||||
class Provider implements ICapabilitySerializable<NBTTagCompound> {
|
||||
DefaultPlayerCapabilitiesProxyContainer instance = (DefaultPlayerCapabilitiesProxyContainer) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getDefaultInstance();
|
||||
@SuppressWarnings("unchecked")
|
||||
DefaultEntityCapabilitiesProxyContainer<Entity> instance = (DefaultEntityCapabilitiesProxyContainer<Entity>) DefaultEntityCapabilitiesProxyContainer.CAPABILITY.getDefaultInstance();
|
||||
|
||||
private final EntityPlayer entity;
|
||||
private final Entity entity;
|
||||
|
||||
Provider(EntityPlayer entity) {
|
||||
Provider(Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
|
||||
return capability == DefaultPlayerCapabilitiesProxyContainer.CAPABILITY;
|
||||
return capability == DefaultEntityCapabilitiesProxyContainer.CAPABILITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
|
||||
if (hasCapability(capability, facing)) {
|
||||
return DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.<T>cast(instance.withEntity(entity));
|
||||
return DefaultEntityCapabilitiesProxyContainer.CAPABILITY.<T>cast(instance.withEntity(entity));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -31,13 +32,13 @@ class Provider implements ICapabilitySerializable<NBTTagCompound> {
|
|||
|
||||
@Override
|
||||
public NBTTagCompound serializeNBT() {
|
||||
return (NBTTagCompound) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage()
|
||||
.writeNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null);
|
||||
return (NBTTagCompound) DefaultEntityCapabilitiesProxyContainer.CAPABILITY.getStorage()
|
||||
.writeNBT(DefaultEntityCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(NBTTagCompound nbt) {
|
||||
DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage()
|
||||
.readNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null, nbt);
|
||||
DefaultEntityCapabilitiesProxyContainer.CAPABILITY.getStorage()
|
||||
.readNBT(DefaultEntityCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null, nbt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
package come.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.Capability.IStorage;
|
||||
|
||||
class Storage implements IStorage<IPlayerCapabilitiesProxyContainer> {
|
||||
class Storage<T extends Entity> implements IStorage<ICapabilitiesProxyContainer<T>> {
|
||||
|
||||
@Override
|
||||
public NBTBase writeNBT(Capability<IPlayerCapabilitiesProxyContainer> capability, IPlayerCapabilitiesProxyContainer instance, EnumFacing side) {
|
||||
public NBTBase writeNBT(Capability<ICapabilitiesProxyContainer<T>> capability, ICapabilitiesProxyContainer<T> instance, EnumFacing side) {
|
||||
return instance.toNBT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(Capability<IPlayerCapabilitiesProxyContainer> capability, IPlayerCapabilitiesProxyContainer instance, EnumFacing side, NBTBase nbt) {
|
||||
public void readNBT(Capability<ICapabilitiesProxyContainer<T>> capability, ICapabilitiesProxyContainer<T> instance, EnumFacing side, NBTBase nbt) {
|
||||
instance.readFromNBT((NBTTagCompound)nbt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"variant=normal": { "model": "unicopia:normal_cloud_block" },
|
||||
"variant=packed": { "model": "unicopia:packed_cloud_block" },
|
||||
"variant=enchanted": { "model": "unicopia:enchanted_cloud_block" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"variants": {
|
||||
"half=bottom,variant=normal": { "model": "unicopia:normal_cloud_block" },
|
||||
"half=bottom,variant=packed": { "model": "unicopia:packed_cloud_block" },
|
||||
"half=bottom,variant=enchanted": { "model": "unicopia:enchanted_cloud_block" },
|
||||
|
||||
"half=top,variant=normal": { "model": "unicopia:normal_cloud_block" },
|
||||
"half=top,variant=packed": { "model": "unicopia:packed_cloud_block" },
|
||||
"half=top,variant=enchanted": { "model": "unicopia:enchanted_cloud_block" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"variants": {
|
||||
"half=bottom,variant=normal": { "model": "unicopia:half_slab_normal_cloud" },
|
||||
"half=top,variant=normal": { "model": "unicopia:upper_slab_normal_cloud" },
|
||||
"half=bottom,variant=packed": { "model": "unicopia:half_slab_packed_cloud" },
|
||||
"half=top,variant=packed": { "model": "unicopia:upper_slab_packed_cloud" },
|
||||
"half=bottom,variant=enchanted": { "model": "unicopia:half_slab_enchanted_cloud" },
|
||||
"half=top,variant=enchanted": { "model": "unicopia:upper_slab_enchanted_cloud" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east,half=bottom,shape=straight": { "model": "unicopia:cloud_stairs" },
|
||||
"facing=west,half=bottom,shape=straight": { "model": "unicopia:cloud_stairs", "y": 180, "uvlock": true },
|
||||
"facing=south,half=bottom,shape=straight": { "model": "unicopia:cloud_stairs", "y": 90, "uvlock": true },
|
||||
"facing=north,half=bottom,shape=straight": { "model": "unicopia:cloud_stairs", "y": 270, "uvlock": true },
|
||||
"facing=east,half=bottom,shape=outer_right": { "model": "unicopia:cloud_outer_stairs" },
|
||||
"facing=west,half=bottom,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "y": 180, "uvlock": true },
|
||||
"facing=south,half=bottom,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "y": 90, "uvlock": true },
|
||||
"facing=north,half=bottom,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "y": 270, "uvlock": true },
|
||||
"facing=east,half=bottom,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "y": 270, "uvlock": true },
|
||||
"facing=west,half=bottom,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "y": 90, "uvlock": true },
|
||||
"facing=south,half=bottom,shape=outer_left": { "model": "unicopia:cloud_outer_stairs" },
|
||||
"facing=north,half=bottom,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "y": 180, "uvlock": true },
|
||||
"facing=east,half=bottom,shape=inner_right": { "model": "unicopia:cloud_inner_stairs" },
|
||||
"facing=west,half=bottom,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "y": 180, "uvlock": true },
|
||||
"facing=south,half=bottom,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "y": 90, "uvlock": true },
|
||||
"facing=north,half=bottom,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "y": 270, "uvlock": true },
|
||||
"facing=east,half=bottom,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "y": 270, "uvlock": true },
|
||||
"facing=west,half=bottom,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "y": 90, "uvlock": true },
|
||||
"facing=south,half=bottom,shape=inner_left": { "model": "unicopia:cloud_inner_stairs" },
|
||||
"facing=north,half=bottom,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "y": 180, "uvlock": true },
|
||||
"facing=east,half=top,shape=straight": { "model": "unicopia:cloud_stairs", "x": 180, "uvlock": true },
|
||||
"facing=west,half=top,shape=straight": { "model": "unicopia:cloud_stairs", "x": 180, "y": 180, "uvlock": true },
|
||||
"facing=south,half=top,shape=straight": { "model": "unicopia:cloud_stairs", "x": 180, "y": 90, "uvlock": true },
|
||||
"facing=north,half=top,shape=straight": { "model": "unicopia:cloud_stairs", "x": 180, "y": 270, "uvlock": true },
|
||||
"facing=east,half=top,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "x": 180, "uvlock": true },
|
||||
"facing=west,half=top,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 180, "uvlock": true },
|
||||
"facing=south,half=top,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 90, "uvlock": true },
|
||||
"facing=north,half=top,shape=outer_right": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 270, "uvlock": true },
|
||||
"facing=east,half=top,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 90, "uvlock": true },
|
||||
"facing=west,half=top,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 270, "uvlock": true },
|
||||
"facing=south,half=top,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "x": 180, "y": 180, "uvlock": true },
|
||||
"facing=north,half=top,shape=outer_left": { "model": "unicopia:cloud_outer_stairs", "x": 180, "uvlock": true },
|
||||
"facing=east,half=top,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "x": 180, "uvlock": true },
|
||||
"facing=west,half=top,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 180, "uvlock": true },
|
||||
"facing=south,half=top,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 90, "uvlock": true },
|
||||
"facing=north,half=top,shape=inner_right": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 270, "uvlock": true },
|
||||
"facing=east,half=top,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 90, "uvlock": true },
|
||||
"facing=west,half=top,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 270, "uvlock": true },
|
||||
"facing=south,half=top,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "x": 180, "y": 180, "uvlock": true },
|
||||
"facing=north,half=top,shape=inner_left": { "model": "unicopia:cloud_inner_stairs", "x": 180, "uvlock": true }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": { "model": "unicopia:enchanted_cloud_block" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"variants": {
|
||||
"half=bottom": { "model": "unicopia:half_slab_enchanted_cloud" },
|
||||
"half=top": { "model": "unicopia:upper_slab_enchanted_cloud" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": { "model": "unicopia:normal_cloud_block" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"variants": {
|
||||
"half=bottom": { "model": "unicopia:half_slab_normal_cloud" },
|
||||
"half=top": { "model": "unicopia:upper_slab_normal_cloud" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": { "model": "unicopia:packed_cloud_block" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"variants": {
|
||||
"half=bottom": { "model": "unicopia:half_slab_packed_cloud" },
|
||||
"half=top": { "model": "unicopia:upper_slab_packed_cloud" }
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
tile.cloudBlock.normal.name=Block of Cloud
|
||||
tile.cloudBlock.packed.name=Dense Cloud
|
||||
tile.cloudBlock.enchanted.name=Enchanted Cloud
|
||||
tile.cloud_block.normal.name=Block of Cloud
|
||||
tile.cloud_block.packed.name=Dense Cloud
|
||||
tile.cloud_block.enchanted.name=Enchanted Cloud
|
||||
|
||||
tile.cloudSlab.normal.name=Cloud Slab
|
||||
tile.cloudSlab.packed.name=Dense Cloud Slab
|
||||
tile.cloudSlab.enchanted.name=Enchanted Cloud Slab
|
||||
tile.cloud_slab.normal.name=Cloud Slab
|
||||
tile.cloud_slab.packed.name=Dense Cloud Slab
|
||||
tile.cloud_slab.enchanted.name=Enchanted Cloud Slab
|
||||
|
||||
tile.stairsCloud.name=Cloud Stairs
|
||||
tile.cloud_stairs.name=Cloud Stairs
|
||||
|
||||
item.cloud_matter.name=Cloud Matter
|
||||
item.cloud.small.name=Small Cloud
|
||||
item.cloud.medium.name=Medium Cloud
|
||||
item.cloud.large.name=Large Cloud
|
||||
item.cloud_matter.name=Lump of Cloud
|
||||
item.cloud.small.name=Bucking Bronco
|
||||
item.cloud.medium.name=Construction Cloud
|
||||
item.cloud.large.name=Wild Cloud
|
||||
|
||||
item.spell.name=Gem
|
||||
item.spell.shield.name=Gem of Repulsion
|
||||
|
@ -29,17 +29,18 @@ item.apple.rotten.name=Rotten Apple
|
|||
item.apple.zap.name=Zap Apple
|
||||
item.apple.zap_cooked.name=Cooked Zap Apple
|
||||
|
||||
entity.cloud.name=Cloud
|
||||
entity.cloud_natural.name=Cloud
|
||||
entity.racing_cloud.name=Bucking Bronco
|
||||
entity.construction_cloud.name=Construction Cloud
|
||||
entity.wild_cloud.name=Cloud
|
||||
entity.spell.name=Magic
|
||||
|
||||
|
||||
commands.race.success.self=Your race has been updated
|
||||
commands.race.success.otherself=%s changed race to %s
|
||||
commands.race.success.other=Changed %s's race to %s
|
||||
commands.race.usage=/race <get|set|list> [player] <species>
|
||||
commands.race.usage=/race <get|set|list|describe> [player] <species>
|
||||
commands.race.list=The available races are:
|
||||
commands.race.permission=Selected Race is not permitted
|
||||
commands.race.permission=Selected Race is not permitted by your current server
|
||||
commands.race.fail="%s" is not a recognised Race
|
||||
|
||||
commands.race.tell.self=You are a
|
||||
|
@ -47,29 +48,59 @@ commands.race.tell.self.alt=You are an
|
|||
commands.race.tell.other=%s is a
|
||||
commands.race.tell.other.alt=%s is an
|
||||
|
||||
commands.race.describe.title=%s
|
||||
commands.race.describe.human.1=This is the default race for new players.
|
||||
commands.race.describe.human.2=It has no special abilities.
|
||||
|
||||
commands.race.describe.earth.1=Earth Ponies can grow crops using mana and punch trees for apples (yeeeeeeehaaaaawwwwwwwwwww)
|
||||
commands.race.describe.earth.2=Their offensive ability is to kick down whilst jumping for a deafening ground smash.
|
||||
commands.race.describe.earth.3=They are strong but slow.
|
||||
|
||||
commands.race.describe.unicorn.1=Unicorns are the primary magic users. They can teleport and cast powerful spells.
|
||||
commands.race.describe.unicorn.2=Their defensive features a powerful shield powered by their mana.
|
||||
commands.race.describe.unicorn.3=They are prone to tiring quickly.
|
||||
|
||||
commands.race.describe.pegasus.1=Pegasi are the masters of the skies.
|
||||
commands.race.describe.pegasus.2=They live mostly in the air and are the only species with the ability to mould and harness cloud materials for their homes.
|
||||
commands.race.describe.pegasus.3=They are fast and light but easy to knock down.
|
||||
|
||||
commands.race.describe.alicorn.1=Praise the sun!
|
||||
commands.race.describe.alicorn.2=Alicorns have all abilities of the other races.
|
||||
commands.race.describe.alicorn.3=Only available to CREATIVE mode players.
|
||||
|
||||
commands.race.describe.changeling.1=Beware the changeling, for they can appear when least expected.
|
||||
commands.race.describe.changeling.2=Changelings can fly but but do not interact with clouds.
|
||||
commands.race.describe.changeling.3=They have to feed on mobs and other players to eat.
|
||||
|
||||
commands.decloud.success=%s clouds removed
|
||||
commands.decloud.usage=/decloud <all>
|
||||
|
||||
unicopia.race.human=Human
|
||||
unicopia.race.human.alt=Humans
|
||||
unicopia.race.earth=Earth Pony
|
||||
unicopia.race.earth.alt=Earth Ponies
|
||||
unicopia.race.unicorn=Unicorn
|
||||
unicopia.race.unicorn.alt=Unicorns
|
||||
unicopia.race.pegasus=Pegasus
|
||||
unicopia.race.pegasus.alt=Pegasi
|
||||
unicopia.race.alicorn=Alicorn
|
||||
unicopia.race.alicorn.alt=Alicorns
|
||||
unicopia.race.changeling=Changeling
|
||||
unicopia.race.changeling.alt=Changelings
|
||||
|
||||
unicopia.category.name=Pony Abilities
|
||||
|
||||
unicopia.power.grow=Earth Pony (Primary)
|
||||
unicopia.power.earth=Earth Pony (Secondary)
|
||||
unicopia.power.grow=Primary Earth Pony ability
|
||||
unicopia.power.earth=Secondary Earth Pony ability
|
||||
|
||||
unicopia.power.teleport=Unicorn (Primary)
|
||||
unicopia.power.magic=Unicorn (Secondary)
|
||||
unicopia.power.teleport=Primary Unicorn ability
|
||||
unicopia.power.magic=Secondary Unicorn ability
|
||||
|
||||
unicopia.power.rain=Pegasus (Primary)
|
||||
unicopia.power.thunder=Pegasus (Secondary)
|
||||
unicopia.power.rain=Primary Pegasus ability
|
||||
unicopia.power.thunder=Secondary Pegasus ability
|
||||
|
||||
unicopia.power.feed=Changeling (Primary)
|
||||
unicopia.power.disguise=Changeling (Secondary)
|
||||
unicopia.power.feed=Primary Changeling ability
|
||||
unicopia.power.disguise=Secondary Changeling ability
|
||||
|
||||
death.attack.feed=%1$s was drained of all life
|
||||
death.attack.feed.player=%1$s died to feed %2$s
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ -90, 0, 0 ],
|
||||
"translation": [ 0, 1, -3 ],
|
||||
"scale": [ 0.55, 0.55, 0.55 ]
|
||||
},
|
||||
"firstperson": {
|
||||
"rotation": [ 0, -135, 25 ],
|
||||
"translation": [ 0, 4, 2 ],
|
||||
"scale": [ 1.7, 1.7, 1.7 ]
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 2, 4, 2 ],
|
||||
"to": [ 14, 12, 14 ],
|
||||
"faces": {
|
||||
"down": { "texture": "#down" },
|
||||
"up": { "texture": "#up" },
|
||||
"north": { "texture": "#north" },
|
||||
"south": { "texture": "#south" },
|
||||
"west": { "texture": "#west" },
|
||||
"east": { "texture": "#east" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/inner_stairs",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_normal",
|
||||
"top": "unicopia:blocks/cloud_normal",
|
||||
"side": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/outer_stairs",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_normal",
|
||||
"top": "unicopia:blocks/cloud_normal",
|
||||
"side": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/stairs",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_normal",
|
||||
"top": "unicopia:blocks/cloud_normal",
|
||||
"side": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "unicopia:blocks/cloud_enchanted"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/half_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_enchanted",
|
||||
"top": "unicopia:blocks/cloud_enchanted",
|
||||
"side": "unicopia:blocks/cloud_enchanted"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/half_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_normal",
|
||||
"top": "unicopia:blocks/cloud_normal",
|
||||
"side": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/half_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_packed",
|
||||
"top": "unicopia:blocks/cloud_packed",
|
||||
"side": "unicopia:blocks/cloud_packed"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "unicopia:blocks/cloud_packed"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/upper_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_enchanted",
|
||||
"top": "unicopia:blocks/cloud_enchanted",
|
||||
"side": "unicopia:blocks/cloud_enchanted"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/upper_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_normal",
|
||||
"top": "unicopia:blocks/cloud_normal",
|
||||
"side": "unicopia:blocks/cloud_normal"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "block/upper_slab",
|
||||
"textures": {
|
||||
"bottom": "unicopia:blocks/cloud_packed",
|
||||
"top": "unicopia:blocks/cloud_packed",
|
||||
"side": "unicopia:blocks/cloud_packed"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "unicopia:block/cloud_cube",
|
||||
"textures": {
|
||||
"all": "unicopia:items/cloud"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "unicopia:items/cloud_matter"
|
||||
},
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ -90, 0, 0 ],
|
||||
"translation": [ 0, 1, -3 ],
|
||||
"scale": [ 0.55, 0.55, 0.55 ]
|
||||
},
|
||||
"firstperson": {
|
||||
"rotation": [ 0, -135, 25 ],
|
||||
"translation": [ 0, 4, 2 ],
|
||||
"scale": [ 1.7, 1.7, 1.7 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "unicopia:block/cloud_cube",
|
||||
"textures": {
|
||||
"all": "unicopia:items/cloud"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "unicopia:block/cloud_cube",
|
||||
"textures": {
|
||||
"all": "unicopia:items/cloud"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "unicopia:block/cloud_stairs"
|
||||
}
|
18
src/main/resources/assets/unicopia/models/item/dew_drop.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "unicopia:items/dew_drop"
|
||||
},
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ -90, 0, 0 ],
|
||||
"translation": [ 0, 1, -3 ],
|
||||
"scale": [ 0.55, 0.55, 0.55 ]
|
||||
},
|
||||
"firstperson": {
|
||||
"rotation": [ 0, -135, 25 ],
|
||||
"translation": [ 0, 4, 2 ],
|
||||
"scale": [ 1.7, 1.7, 1.7 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/enchanted_cloud_block",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/half_slab_enchanted_cloud",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/normal_cloud_block",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/half_slab_normal_cloud",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/packed_cloud_block",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"parent": "unicopia:block/half_slab_packed_cloud",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
BIN
src/main/resources/assets/unicopia/textures/entity/clouds.png
Normal file
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 21 KiB |
BIN
src/main/resources/assets/unicopia/textures/items/cloud.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
BIN
src/main/resources/assets/unicopia/textures/items/dew_drop.png
Normal file
After Width: | Height: | Size: 145 B |