diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityButterfly.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityButterfly.java new file mode 100644 index 00000000..1c0fcae4 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityButterfly.java @@ -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 RESTING = EntityDataManager.createKey(EntityButterfly.class, DataSerializers.BOOLEAN); + + private static final DataParameter 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)]; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/init/UEntities.java b/src/main/java/com/minelittlepony/unicopia/init/UEntities.java index e955160c..cd231436 100644 --- a/src/main/java/com/minelittlepony/unicopia/init/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/init/UEntities.java @@ -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 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); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java b/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java index 141dfe75..5e0fe3b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java @@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.mixin; import java.lang.reflect.Field; -public class FieldAccessor { +class FieldAccessor { private boolean init; private Field field; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java index 2367cdf0..ae326af7 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java @@ -18,6 +18,7 @@ public interface MixinEntity { return PLAYER_MODEL_FLAG; } } + abstract class Shulker { private static final FieldAccessor __peekAmount = new FieldAccessor<>(EntityShulker.class, 8); diff --git a/src/main/java/com/minelittlepony/unicopia/model/ModelButterfly.java b/src/main/java/com/minelittlepony/unicopia/model/ModelButterfly.java new file mode 100644 index 00000000..95a6678b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/model/ModelButterfly.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/render/RenderButterfly.java b/src/main/java/com/minelittlepony/unicopia/render/RenderButterfly.java new file mode 100644 index 00000000..d42d9945 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/render/RenderButterfly.java @@ -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 { + + 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); + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_US.lang b/src/main/resources/assets/unicopia/lang/en_US.lang index 3f0635de..bf497e36 100644 --- a/src/main/resources/assets/unicopia/lang/en_US.lang +++ b/src/main/resources/assets/unicopia/lang/en_US.lang @@ -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 diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/blue.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/blue.png new file mode 100644 index 00000000..05f741bd Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/blue.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/brimstone.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/brimstone.png new file mode 100644 index 00000000..b19268ad Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/brimstone.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/butterfly.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/butterfly.png new file mode 100644 index 00000000..7dcebd91 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/butterfly.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/green.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/green.png new file mode 100644 index 00000000..e68882b9 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/green.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/hedylidae.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/hedylidae.png new file mode 100644 index 00000000..c53c52c8 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/hedylidae.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/lime.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/lime.png new file mode 100644 index 00000000..29105c0f Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/lime.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/lycaenidae.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/lycaenidae.png new file mode 100644 index 00000000..05bbb7fd Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/lycaenidae.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/magenta.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/magenta.png new file mode 100644 index 00000000..d0be31d9 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/magenta.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/monarch.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/monarch.png new file mode 100644 index 00000000..1cec4597 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/monarch.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/nymphalidae.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/nymphalidae.png new file mode 100644 index 00000000..11c113ca Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/nymphalidae.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/pink.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/pink.png new file mode 100644 index 00000000..d5f080ad Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/pink.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/purple.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/purple.png new file mode 100644 index 00000000..ac8c7e1b Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/purple.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/red.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/red.png new file mode 100644 index 00000000..380ad7fc Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/red.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/white_monarch.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/white_monarch.png new file mode 100644 index 00000000..bed08d52 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/white_monarch.png differ diff --git a/src/main/resources/assets/unicopia/textures/entity/butterfly/yellow.png b/src/main/resources/assets/unicopia/textures/entity/butterfly/yellow.png new file mode 100644 index 00000000..2c991be9 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/entity/butterfly/yellow.png differ