Added butterflies
|
@ -0,0 +1,224 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.entity.passive.EntityAmbientCreature;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome.SpawnListEntry;
|
||||
|
||||
public class EntityButterfly extends EntityAmbientCreature {
|
||||
|
||||
public static final SpawnListEntry SPAWN_ENTRY = new SpawnListEntry(EntityButterfly.class, 15, 9, 15);
|
||||
|
||||
private static final DataParameter<Boolean> RESTING = EntityDataManager.createKey(EntityButterfly.class, DataSerializers.BOOLEAN);
|
||||
|
||||
private static final DataParameter<Integer> VARIANT = EntityDataManager.createKey(EntityButterfly.class, DataSerializers.VARINT);
|
||||
|
||||
private BlockPos hoveringPosition;
|
||||
|
||||
public EntityButterfly(World world) {
|
||||
super(world);
|
||||
|
||||
preventEntitySpawning = false;
|
||||
width = 0.1F;
|
||||
height = 0.1F;
|
||||
|
||||
setVariaty(Variant.random(world.rand));
|
||||
setResting(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
dataManager.register(VARIANT, Variant.BUTTERFLY.ordinal());
|
||||
dataManager.register(RESTING, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBePushed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collideWithEntity(Entity entity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collideWithNearbyEntities() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
|
||||
motionY *= 0.6;
|
||||
}
|
||||
|
||||
public boolean isResting() {
|
||||
return dataManager.get(RESTING);
|
||||
}
|
||||
|
||||
public void setResting(boolean resting) {
|
||||
dataManager.set(RESTING, resting);
|
||||
}
|
||||
|
||||
public Variant getVariety() {
|
||||
Variant[] values = Variant.values();
|
||||
return values[dataManager.get(VARIANT) % values.length];
|
||||
}
|
||||
|
||||
public void setVariaty(Variant variant) {
|
||||
dataManager.set(VARIANT, variant.ordinal());
|
||||
}
|
||||
|
||||
protected boolean isAggressor(Entity e) {
|
||||
if (e instanceof EntityButterfly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e instanceof EntityPlayer) {
|
||||
EntityPlayer player = (EntityPlayer)e;
|
||||
|
||||
if (player.isCreative() || player.isSpectator()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.isSprinting() || player.isSwingInProgress || player.moveForward > 0 || player.moveStrafing > 0) {
|
||||
return true;
|
||||
}
|
||||
} else if (!IMob.VISIBLE_MOB_SELECTOR.test(e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Math.abs(e.motionX) > 0 || Math.abs(e.motionZ) > 0;
|
||||
}
|
||||
|
||||
protected void updateAITasks() {
|
||||
super.updateAITasks();
|
||||
|
||||
BlockPos pos = getPosition();
|
||||
BlockPos below = pos.down();
|
||||
|
||||
if (isResting()) {
|
||||
if (world.getBlockState(below).isNormalCube()) {
|
||||
if (world.getEntitiesWithinAABBExcludingEntity(this, getEntityBoundingBox().grow(7)).stream().anyMatch(this::isAggressor)) {
|
||||
setResting(false);
|
||||
}
|
||||
} else {
|
||||
setResting(false);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// invalidate the hovering position
|
||||
if (hoveringPosition != null && (!world.isAirBlock(hoveringPosition) || hoveringPosition.getY() < 1)) {
|
||||
hoveringPosition = null;
|
||||
}
|
||||
|
||||
// select a new hovering position
|
||||
if (hoveringPosition == null || rand.nextInt(30) == 0 || hoveringPosition.distanceSq(posX, posY, posZ) < 4) {
|
||||
hoveringPosition = new BlockPos(posX + rand.nextInt(7) - rand.nextInt(7), posY + rand.nextInt(6) - 2, posZ + rand.nextInt(7) - rand.nextInt(7));
|
||||
}
|
||||
|
||||
// hover casually towards the chosen position
|
||||
|
||||
double changedX = hoveringPosition.getX() + 0.5D - posX;
|
||||
double changedY = hoveringPosition.getY() + 0.1D - posY;
|
||||
double changedZ = hoveringPosition.getZ() + 0.5D - posZ;
|
||||
|
||||
motionX += (Math.signum(changedX) * 0.5D - motionX) * 0.10000000149011612D;
|
||||
motionY += (Math.signum(changedY) * 0.699999988079071D - motionY) * 0.10000000149011612D;
|
||||
motionZ += (Math.signum(changedZ) * 0.5D - motionZ) * 0.10000000149011612D;
|
||||
|
||||
float f = (float)(MathHelper.atan2(motionZ, motionX) * (180 / Math.PI)) - 90;
|
||||
|
||||
moveForward = 0.5F;
|
||||
rotationYaw += MathHelper.wrapDegrees(f - rotationYaw);
|
||||
|
||||
if (rand.nextInt(100) == 0 && world.getBlockState(below).isNormalCube()) {
|
||||
setResting(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canTriggerWalking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fall(float distance, float damageMultiplier) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesEntityNotTriggerPressurePlate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere() {
|
||||
if (posY < world.getSeaLevel()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return world.getLightFromNeighbors(getPosition()) > 7
|
||||
&& super.getCanSpawnHere();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getEyeHeight() {
|
||||
return height / 2;
|
||||
}
|
||||
|
||||
public static enum Variant {
|
||||
BUTTERFLY,
|
||||
YELLOW,
|
||||
LIME,
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE,
|
||||
PURPLE,
|
||||
MAGENTA,
|
||||
PINK,
|
||||
HEDYLIDAE,
|
||||
LYCAENIDAE,
|
||||
NYMPHALIDAE,
|
||||
MONARCH,
|
||||
WHITE_MONARCH,
|
||||
BRIMSTONE;
|
||||
|
||||
private final ResourceLocation skin = new ResourceLocation(Unicopia.MODID, "textures/entity/butterfly/" + name().toLowerCase() + ".png");
|
||||
|
||||
public ResourceLocation getSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
static Variant random(Random rand) {
|
||||
Variant[] values = values();
|
||||
return values[rand.nextInt(values.length)];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.init;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.EntityButterfly;
|
||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
||||
import com.minelittlepony.unicopia.entity.EntityCuccoon;
|
||||
|
@ -12,6 +13,7 @@ import com.minelittlepony.unicopia.entity.EntityProjectile;
|
|||
import com.minelittlepony.unicopia.entity.EntityWildCloud;
|
||||
import com.minelittlepony.unicopia.forgebullshit.BiomeBS;
|
||||
import com.minelittlepony.unicopia.forgebullshit.EntityType;
|
||||
import com.minelittlepony.unicopia.render.RenderButterfly;
|
||||
import com.minelittlepony.unicopia.render.RenderCloud;
|
||||
import com.minelittlepony.unicopia.render.RenderCuccoon;
|
||||
import com.minelittlepony.unicopia.render.RenderGem;
|
||||
|
@ -22,27 +24,30 @@ import com.minelittlepony.unicopia.render.RenderSpellbook;
|
|||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeEnd;
|
||||
import net.minecraft.world.biome.BiomeForest;
|
||||
import net.minecraft.world.biome.BiomeHell;
|
||||
import net.minecraft.world.biome.BiomeHills;
|
||||
import net.minecraft.world.biome.BiomePlains;
|
||||
import net.minecraft.world.biome.BiomeRiver;
|
||||
import net.minecraftforge.common.BiomeManager;
|
||||
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 = 0x4169E1;
|
||||
private static final int BRUSHES_CHARTREUSE = 0x7FFF00;
|
||||
|
||||
static void init(IForgeRegistry<EntityEntry> registry) {
|
||||
EntityType builder = EntityType.builder(Unicopia.MODID);
|
||||
registry.registerAll(
|
||||
builder.creature(EntityCloud.class, "cloud").withEgg(BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE),
|
||||
builder.creature(EntityCloud.class, "cloud").withEgg(0x4169e1, 0x7fff00),
|
||||
builder.creature(EntityWildCloud.class, "wild_cloud"),
|
||||
builder.creature(EntityRacingCloud.class, "racing_cloud"),
|
||||
builder.creature(EntityConstructionCloud.class, "construction_cloud"),
|
||||
builder.creature(EntitySpell.class, "magic_spell"),
|
||||
builder.creature(EntitySpellbook.class, "spellbook"),
|
||||
builder.creature(EntityRainbow.Spawner.class, "rainbow_spawner"),
|
||||
builder.creature(EntityCuccoon.class, "cuccoon").withEgg(0, 0),
|
||||
builder.creature(EntityCuccoon.class, "cuccoon"),
|
||||
builder.creature(EntityButterfly.class, "butterfly").withEgg(0x222200, 0xaaeeff),
|
||||
builder.projectile(EntityRainbow.class, "rainbow", 500, 5),
|
||||
builder.projectile(EntityProjectile.class, "thrown_item", 100, 10)
|
||||
);
|
||||
|
@ -54,6 +59,7 @@ public class UEntities {
|
|||
RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpellbook.class, RenderSpellbook::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, RenderRainbow::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityButterfly.class, RenderButterfly::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityCuccoon.class, RenderCuccoon::new);
|
||||
}
|
||||
|
||||
|
@ -63,7 +69,15 @@ public class UEntities {
|
|||
BiomeBS.addSpawnEntry(biome, EnumCreatureType.AMBIENT, EntityWildCloud.class, b ->
|
||||
BiomeManager.oceanBiomes.contains(b) ? EntityWildCloud.SPAWN_ENTRY_LAND : EntityWildCloud.SPAWN_ENTRY_OCEAN
|
||||
);
|
||||
|
||||
BiomeBS.addSpawnEntry(biome, EnumCreatureType.CREATURE, EntityRainbow.Spawner.class, b -> EntityRainbow.SPAWN_ENTRY);
|
||||
}
|
||||
|
||||
if (biome instanceof BiomePlains
|
||||
|| biome instanceof BiomeRiver
|
||||
|| biome instanceof BiomeHills
|
||||
|| biome instanceof BiomeForest) {
|
||||
BiomeBS.addSpawnEntry(biome, EnumCreatureType.AMBIENT, EntityButterfly.class, b -> EntityButterfly.SPAWN_ENTRY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.mixin;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class FieldAccessor<Owner, Type> {
|
||||
class FieldAccessor<Owner, Type> {
|
||||
|
||||
private boolean init;
|
||||
private Field field;
|
||||
|
|
|
@ -18,6 +18,7 @@ public interface MixinEntity {
|
|||
return PLAYER_MODEL_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Shulker {
|
||||
private static final FieldAccessor<EntityShulker, Float> __peekAmount = new FieldAccessor<>(EntityShulker.class, 8);
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package com.minelittlepony.unicopia.model;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityButterfly;
|
||||
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class ModelButterfly extends ModelBase {
|
||||
|
||||
private ModelRenderer body;
|
||||
|
||||
private ModelRenderer leftWingInner;
|
||||
private ModelRenderer leftWingOuter;
|
||||
|
||||
private ModelRenderer rightWingInner;
|
||||
private ModelRenderer rightWingOuter;
|
||||
|
||||
public ModelButterfly() {
|
||||
textureWidth = 64;
|
||||
textureHeight = 64;
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
void init() {
|
||||
this.boxList.clear();
|
||||
|
||||
body = new ModelRenderer(this, 0, 0);
|
||||
body.rotationPointZ = -10;
|
||||
body.rotationPointY = 12;
|
||||
|
||||
rightWingInner = new ModelRenderer(this, 42, 0);
|
||||
rightWingInner.rotateAngleZ = -0.2F;
|
||||
rightWingInner.addBox(-13, -5, 0, 10, 19, 1);
|
||||
|
||||
body.addChild(rightWingInner);
|
||||
|
||||
rightWingOuter = new ModelRenderer(this, 24, 16);
|
||||
rightWingOuter.setRotationPoint(-13, 10, 0.1F);
|
||||
rightWingOuter.rotateAngleZ = -0.2F;
|
||||
rightWingOuter.addBox(0, 0, 0, 10, 12, 1);
|
||||
|
||||
rightWingInner.addChild(rightWingOuter);
|
||||
|
||||
leftWingInner = new ModelRenderer(this, 42, 0);
|
||||
leftWingInner.mirror = true;
|
||||
leftWingInner.rotateAngleZ = 0.2F;
|
||||
leftWingInner.addBox(2, -5, 0, 10, 19, 1);
|
||||
|
||||
body.addChild(leftWingInner);
|
||||
|
||||
leftWingOuter = new ModelRenderer(this, 24, 16);
|
||||
leftWingOuter.mirror = true;
|
||||
leftWingOuter.rotateAngleZ = -0.2F;
|
||||
leftWingOuter.setRotationPoint(2, 10, 0.1F);
|
||||
leftWingOuter.addBox(0, 0, 0, 10, 12, 1);
|
||||
|
||||
leftWingInner.addChild(leftWingOuter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||
|
||||
setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entityIn);
|
||||
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
body.render(scale);
|
||||
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) {
|
||||
|
||||
float flap = MathHelper.cos(ageInTicks) * (float)Math.PI / 4;
|
||||
|
||||
if (((EntityButterfly)entity).isResting()) {
|
||||
body.rotateAngleX = 0.8F;
|
||||
flap = MathHelper.cos(ageInTicks / 10) * (float)Math.PI / 6 + 0.7F;
|
||||
} else {
|
||||
body.rotateAngleX = ((float)Math.PI / 4) + MathHelper.cos(ageInTicks * 0.1F) * 0.15F;
|
||||
}
|
||||
|
||||
rightWingInner.rotateAngleY = flap;
|
||||
leftWingInner.rotateAngleY = -flap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.minelittlepony.unicopia.render;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityButterfly;
|
||||
import com.minelittlepony.unicopia.model.ModelButterfly;
|
||||
|
||||
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 net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class RenderButterfly extends RenderLiving<EntityButterfly> {
|
||||
|
||||
public RenderButterfly(RenderManager rm) {
|
||||
super(rm, new ModelButterfly(), 0.25F);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityButterfly entity) {
|
||||
return entity.getVariety().getSkin();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRenderCallback(EntityButterfly entity, float ticks) {
|
||||
GlStateManager.scale(0.35F, 0.35F, 0.35F);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyRotations(EntityButterfly entity, float age, float yaw, float ticks) {
|
||||
|
||||
if (!entity.isResting()) {
|
||||
GlStateManager.translate(0, MathHelper.cos(age / 3F) / 10F, 0);
|
||||
}
|
||||
|
||||
super.applyRotations(entity, age, yaw, ticks);
|
||||
}
|
||||
}
|
|
@ -172,6 +172,7 @@ entity.construction_cloud.name=Construction Cloud
|
|||
entity.cloud.name=Cloud
|
||||
entity.spell.name=Magic
|
||||
entity.spellbook.name=Spellbook
|
||||
entity.butterfly.name=Butterfly
|
||||
|
||||
toxicity.safe.name=Safe
|
||||
toxicity.mild.name=Mildly Toxic
|
||||
|
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 2.9 KiB |