From 79a5f215deb7ebe1ba80a438a84b2c943c80b18d Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 8 Mar 2019 22:56:25 +0200 Subject: [PATCH] Added a cuccoon entity (WIP) --- .../unicopia/entity/EntityCuccoon.java | 240 ++++++++++++++++++ .../unicopia/init/UEntities.java | 4 + .../unicopia/model/ModelCuccoon.java | 75 ++++++ .../unicopia/player/PlayerCapabilities.java | 15 +- .../unicopia/render/RenderCuccoon.java | 54 ++++ 5 files changed, 385 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/EntityCuccoon.java create mode 100644 src/main/java/com/minelittlepony/unicopia/model/ModelCuccoon.java create mode 100644 src/main/java/com/minelittlepony/unicopia/render/RenderCuccoon.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityCuccoon.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityCuccoon.java new file mode 100644 index 00000000..5f0839de --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityCuccoon.java @@ -0,0 +1,240 @@ +package com.minelittlepony.unicopia.entity; + +import java.util.List; + +import javax.annotation.Nullable; + +import com.google.common.collect.Lists; +import com.minelittlepony.unicopia.Predicates; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.init.USounds; + +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.EnumHandSide; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; + +public class EntityCuccoon extends EntityLivingBase implements IMagicals, IInAnimate { + + private static final DataParameter STRUGGLE_COUNT = EntityDataManager.createKey(EntityCuccoon.class, DataSerializers.VARINT); + + private final List armour = Lists.newArrayList(); + + private boolean captiveLastSneakState; + + public EntityCuccoon(World world) { + super(world); + setSize(0.6f, 0.6f); + + width = 1.5F; + height = 1.6F; + } + + @Override + protected void entityInit() { + super.entityInit(); + getDataManager().register(STRUGGLE_COUNT, 0); + } + + public int getStruggleCount() { + return getDataManager().get(STRUGGLE_COUNT) % 6; + } + + public void setStruggleCount(int count) { + getDataManager().set(STRUGGLE_COUNT, count % 6); + } + + @Override + protected boolean canBeRidden(Entity entity) { + return super.canBeRidden(entity) + && !entity.isSneaking() + && !isBeingRidden() + && entity instanceof EntityLivingBase + && !Predicates.BUGGY.test(entity); + } + + @Override + public boolean canRenderOnFire() { + return false; + } + + @Override + protected boolean canTriggerWalking() { + return false; + } + + @Override + public double getMountedYOffset() { + return 0; + } + + @Override + public boolean canPassengerSteer() { + return false; + } + + @Override + public void onUpdate() { + super.onUpdate(); + + if (isBeingRidden()) { + Entity passenger = getPassengers().get(0); + + boolean sneaking = passenger.isSneaking(); + + if (sneaking && !attemptDismount(passenger)) { + passenger.setSneaking(false); + } + + captiveLastSneakState = sneaking; + } + + if (world.isRemote) { + double x = posX + width * world.rand.nextFloat() - width/2; + double y = posY + height * world.rand.nextFloat(); + double z = posZ + width * world.rand.nextFloat() - width/2; + + world.spawnParticle(EnumParticleTypes.DRIP_LAVA, x, y, z, 0, 0, 0); + } + } + + public float getBreatheAmount(float stutter) { + return MathHelper.sin((ticksExisted + stutter) / 40) / 2 + + hurtTime / 10F; + } + + @Override + public boolean attackable() { + return false; + } + + public boolean attemptDismount(Entity captive) { + if (captive.isSneaking() != captiveLastSneakState) { + setStruggleCount(getStruggleCount() + 1); + + for (int k = 0; k < 20; k++) { + double d2 = rand.nextGaussian() * 0.02; + double d0 = rand.nextGaussian() * 0.02; + double d1 = rand.nextGaussian() * 0.02; + + world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, + posX + rand.nextFloat() * width * 2 - width, + posY + rand.nextFloat() * height, + posZ + rand.nextFloat() * width * 2 - width, + d2, d0, d1, Block.getStateId(Blocks.SLIME_BLOCK.getDefaultState())); + } + + captive.playSound(USounds.SLIME_RETRACT, 1, 1); + this.hurtTime += 15; + + if (getStruggleCount() == 0) { + setDead(); + + return true; + } + } + + return false; + } + + @Override + protected void onDeathUpdate() { + if (++deathTime == 20) { + if (!world.isRemote && (isPlayer() || recentlyHit > 0 && canDropLoot() && world.getGameRules().getBoolean("doMobLoot"))) { + int i = ForgeEventFactory.getExperienceDrop(this, attackingPlayer, getExperiencePoints(attackingPlayer)); + + while (i > 0) { + int j = EntityXPOrb.getXPSplit(i); + + i -= j; + + world.spawnEntity(new EntityXPOrb(world, posX, posY, posZ, j)); + } + + this.dismountRidingEntity(); + } + + setDead(); + + for (int k = 0; k < 20; k++) { + double d2 = rand.nextGaussian() * 0.02; + double d0 = rand.nextGaussian() * 0.02; + double d1 = rand.nextGaussian() * 0.02; + + world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, + posX + rand.nextFloat() * width * 2 - width, + posY + rand.nextFloat() * height, + posZ + rand.nextFloat() * width * 2 - width, + d2, d0, d1, Block.getStateId(Blocks.SLIME_BLOCK.getDefaultState())); + } + } + } + + @Nullable + public AxisAlignedBB getCollisionBox(Entity entity) { + return entity.canBeCollidedWith() ? entity.getEntityBoundingBox() : null; + } + + @Nullable + public AxisAlignedBB getCollisionBoundingBox() { + return getEntityBoundingBox().shrink(0.2); + } + + @Override + protected void collideWithEntity(Entity entity) { + if (canBeRidden(entity)) { + entity.playSound(USounds.SLIME_ADVANCE, 1, 1); + entity.startRiding(this, true); + } else { + super.collideWithEntity(entity); + } + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + } + + @Override + public boolean canInteract(Race race) { + return race == Race.CHANGELING; + } + + @Override + public Iterable getArmorInventoryList() { + return armour; + } + + @Override + public ItemStack getItemStackFromSlot(EntityEquipmentSlot slotIn) { + return ItemStack.EMPTY; + } + + @Override + public void setItemStackToSlot(EntityEquipmentSlot slotIn, ItemStack stack) { + + } + + @Override + public EnumHandSide getPrimaryHand() { + return EnumHandSide.LEFT; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/init/UEntities.java b/src/main/java/com/minelittlepony/unicopia/init/UEntities.java index 4647b233..65dc2563 100644 --- a/src/main/java/com/minelittlepony/unicopia/init/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/init/UEntities.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.init; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.entity.EntityCloud; import com.minelittlepony.unicopia.entity.EntityConstructionCloud; +import com.minelittlepony.unicopia.entity.EntityCuccoon; import com.minelittlepony.unicopia.entity.EntityRacingCloud; import com.minelittlepony.unicopia.entity.EntityRainbow; import com.minelittlepony.unicopia.entity.EntitySpell; @@ -12,6 +13,7 @@ import com.minelittlepony.unicopia.entity.EntityWildCloud; import com.minelittlepony.unicopia.forgebullshit.BiomeBS; import com.minelittlepony.unicopia.forgebullshit.EntityType; import com.minelittlepony.unicopia.render.RenderCloud; +import com.minelittlepony.unicopia.render.RenderCuccoon; import com.minelittlepony.unicopia.render.RenderGem; import com.minelittlepony.unicopia.render.RenderProjectile; import com.minelittlepony.unicopia.render.RenderRainbow; @@ -40,6 +42,7 @@ public class UEntities { 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.projectile(EntityRainbow.class, "rainbow", 500, 5), builder.projectile(EntityProjectile.class, "thrown_item", 10, 5) ); @@ -51,6 +54,7 @@ public class UEntities { RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new); RenderingRegistry.registerEntityRenderingHandler(EntitySpellbook.class, RenderSpellbook::new); RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, RenderRainbow::new); + RenderingRegistry.registerEntityRenderingHandler(EntityCuccoon.class, RenderCuccoon::new); } public static void registerSpawnEntries(Biome biome) { diff --git a/src/main/java/com/minelittlepony/unicopia/model/ModelCuccoon.java b/src/main/java/com/minelittlepony/unicopia/model/ModelCuccoon.java new file mode 100644 index 00000000..2c69b13c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/model/ModelCuccoon.java @@ -0,0 +1,75 @@ +package com.minelittlepony.unicopia.model; + +import com.minelittlepony.unicopia.entity.EntityCuccoon; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.GlStateManager.DestFactor; +import net.minecraft.client.renderer.GlStateManager.SourceFactor; +import net.minecraft.entity.Entity; + +public class ModelCuccoon extends ModelBase { + + ModelRenderer body; + + public ModelCuccoon() { + init(); + } + + private void init() { + boxList.clear(); + + body = new ModelRenderer(this, 0, 0); + body.setTextureSize(250, 250); + + body.setTextureOffset(0, 0); + + // cuccoon shape + body.addBox(-4, -2, -4, 8, 2, 8); + body.addBox(-7.5F, 0, -7.5F, 15, 6, 15); + body.addBox(-10, 4, -10, 20, 6, 20); + body.addBox(-11.5F, 10, -11.5F, 23, 8, 23); + body.addBox(-10, 17, -10, 20, 6, 20); + body.addBox(-11.5F, 22, -11.5F, 23, 2, 23); + + + // pile of blocks + // body.addBox(-10, offsetY + 10, -10, 12, 12, 12); + // body.addBox(-14, offsetY + 14, 4, 10, 10, 10); + // body.addBox(-17, offsetY + 17, 3, 8, 8, 8); + // body.addBox(0, offsetY + 10, 0, 12, 12, 12); + // body.addBox(-7, offsetY + 6, -7, 16, 16, 16); + // body.addBox(-7, offsetY + 0, -7, 12, 12, 12); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + + float breatheAmount = ((EntityCuccoon)entity).getBreatheAmount(ageInTicks) / 8; + + GlStateManager.pushMatrix(); + + GlStateManager.enableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableNormalize(); + + GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); + + GlStateManager.scale(1 - breatheAmount, 1 + breatheAmount, 1 - breatheAmount); + GlStateManager.translate(0, -breatheAmount * 1.3F, 0); + + body.render(scale); + + GlStateManager.scale(0.9, 0.9, 0.9); + GlStateManager.translate(0, 0.2F, 0); + + body.render(scale); + + GlStateManager.disableNormalize(); + GlStateManager.disableAlpha(); + GlStateManager.disableBlend(); + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java b/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java index a27525ca..e1920d82 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java @@ -10,6 +10,7 @@ import com.minelittlepony.model.anim.IInterpolator; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.enchanting.PageState; +import com.minelittlepony.unicopia.entity.EntityCuccoon; import com.minelittlepony.unicopia.init.UEffects; import com.minelittlepony.unicopia.init.UItems; import com.minelittlepony.unicopia.item.ICastable; @@ -221,10 +222,18 @@ class PlayerCapabilities implements IPlayer { Entity ridee = entity.getRidingEntity(); - entity.dismountRidingEntity(); + if (ridee instanceof EntityCuccoon) { + if (((EntityCuccoon)ridee).attemptDismount(entity)) { + entity.dismountRidingEntity(); + } else { + entity.setSneaking(false); + } + } else { + entity.dismountRidingEntity(); - if (ridee instanceof EntityPlayerMP) { - ((EntityPlayerMP)ridee).getServerWorld().getEntityTracker().sendToTrackingAndSelf(ridee, new SPacketSetPassengers(ridee)); + if (ridee instanceof EntityPlayerMP) { + ((EntityPlayerMP)ridee).getServerWorld().getEntityTracker().sendToTrackingAndSelf(ridee, new SPacketSetPassengers(ridee)); + } } } } diff --git a/src/main/java/com/minelittlepony/unicopia/render/RenderCuccoon.java b/src/main/java/com/minelittlepony/unicopia/render/RenderCuccoon.java new file mode 100644 index 00000000..5d105858 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/render/RenderCuccoon.java @@ -0,0 +1,54 @@ +package com.minelittlepony.unicopia.render; + +import com.minelittlepony.unicopia.UClient; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.entity.EntityCuccoon; +import com.minelittlepony.unicopia.model.ModelCuccoon; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; + +public class RenderCuccoon extends RenderLivingBase { + + private static final ResourceLocation TEXTURE = new ResourceLocation(Unicopia.MODID, "textures/entity/cuccoon.png"); + + public RenderCuccoon(RenderManager manager) { + super(manager, new ModelCuccoon(), 1); + } + + @Override + protected ResourceLocation getEntityTexture(EntityCuccoon entity) { + return TEXTURE; + } + + @Override + protected float getDeathMaxRotation(EntityCuccoon entity) { + return 0; + } + + @Override + public void doRender(EntityCuccoon entity, double x, double y, double z, float entityYaw, float partialTicks) { + + if (entity.isBeingRidden()) { + Entity rider = entity.getPassengers().get(0); + + if (!(rider == Minecraft.getMinecraft().player) || UClient.instance().getViewMode() != 0) { + GlStateManager.enableAlpha(); + GlStateManager.enableBlend(); + + renderManager.renderEntity(rider, x, y + rider.getYOffset(), z, entityYaw, partialTicks, true); + + GlStateManager.disableBlend(); + GlStateManager.disableAlpha(); + } + + + } + + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } +}