Added butterflies

This commit is contained in:
Sollace 2019-03-21 17:03:59 +02:00
parent 6ab9343164
commit 64666e8e60
22 changed files with 373 additions and 5 deletions

View file

@ -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)];
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB