From 7027b6d40a6ca1003ffcbbe2a84cfe399ce9cf4d Mon Sep 17 00:00:00 2001 From: HoosierTransfer <97118529+HoosierTransfer@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:04:40 -0400 Subject: [PATCH] idk if this works --- .../textures/entity/shulker/endergolem.png | Bin 0 -> 1980 bytes .../textures/entity/shulker/spark.png | Bin 0 -> 847 bytes .../textures/entity/shulker/endergolem.png | Bin 0 -> 1980 bytes .../textures/entity/shulker/spark.png | Bin 0 -> 847 bytes .../minecraft/client/model/ModelShulker.java | 83 ++ .../client/model/ModelShulkerBullet.java | 40 + .../client/network/NetHandlerPlayClient.java | 10 +- .../client/renderer/entity/RenderManager.java | 5 + .../client/renderer/entity/RenderShulker.java | 197 +++++ .../renderer/entity/RenderShulkerBullet.java | 70 ++ .../net/minecraft/entity/DataWatcher.java | 3 +- .../java/net/minecraft/entity/EntityList.java | 8 + .../net/minecraft/entity/EntityTracker.java | 5 +- .../minecraft/entity/EntityTrackerEntry.java | 9 +- .../entity/monster/EntityShulker.java | 754 ++++++++++++++++++ .../projectile/EntityShulkerBullet.java | 434 ++++++++++ .../entity/projectile/ProjectileHelper.java | 99 +++ src/main/java/net/minecraft/nbt/NBTUtil.java | 16 + .../java/net/minecraft/util/DamageSource.java | 5 + .../net/minecraft/util/EntitySelectors.java | 11 + .../minecraft/util/math/AxisAlignedBB.java | 9 + .../net/minecraft/util/math/MathHelper.java | 14 + 22 files changed, 1767 insertions(+), 5 deletions(-) create mode 100644 desktopRuntime/resources/assets/minecraft/textures/entity/shulker/endergolem.png create mode 100644 desktopRuntime/resources/assets/minecraft/textures/entity/shulker/spark.png create mode 100644 resources/resources/assets/minecraft/textures/entity/shulker/endergolem.png create mode 100644 resources/resources/assets/minecraft/textures/entity/shulker/spark.png create mode 100644 src/main/java/net/minecraft/client/model/ModelShulker.java create mode 100644 src/main/java/net/minecraft/client/model/ModelShulkerBullet.java create mode 100644 src/main/java/net/minecraft/client/renderer/entity/RenderShulker.java create mode 100644 src/main/java/net/minecraft/client/renderer/entity/RenderShulkerBullet.java create mode 100644 src/main/java/net/minecraft/entity/monster/EntityShulker.java create mode 100644 src/main/java/net/minecraft/entity/projectile/EntityShulkerBullet.java create mode 100644 src/main/java/net/minecraft/entity/projectile/ProjectileHelper.java diff --git a/desktopRuntime/resources/assets/minecraft/textures/entity/shulker/endergolem.png b/desktopRuntime/resources/assets/minecraft/textures/entity/shulker/endergolem.png new file mode 100644 index 0000000000000000000000000000000000000000..d569779501c88f12db3dfa1b3ec39bcfe3019bc6 GIT binary patch literal 1980 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 Z$`|7I+*+YCL3RKD002ovPDHLkV1n}6bQ}Nx literal 0 HcmV?d00001 diff --git a/resources/resources/assets/minecraft/textures/entity/shulker/endergolem.png b/resources/resources/assets/minecraft/textures/entity/shulker/endergolem.png new file mode 100644 index 0000000000000000000000000000000000000000..d569779501c88f12db3dfa1b3ec39bcfe3019bc6 GIT binary patch literal 1980 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 Z$`|7I+*+YCL3RKD002ovPDHLkV1n}6bQ}Nx literal 0 HcmV?d00001 diff --git a/src/main/java/net/minecraft/client/model/ModelShulker.java b/src/main/java/net/minecraft/client/model/ModelShulker.java new file mode 100644 index 0000000..df5aed8 --- /dev/null +++ b/src/main/java/net/minecraft/client/model/ModelShulker.java @@ -0,0 +1,83 @@ +package net.minecraft.client.model; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityShulker; +import net.minecraft.util.math.MathHelper; + +public class ModelShulker extends ModelBase +{ + private ModelRenderer base; + private ModelRenderer lid; + public ModelRenderer head; + + public ModelShulker() + { + this.textureHeight = 64; + this.textureWidth = 64; + this.lid = new ModelRenderer(this); + this.base = new ModelRenderer(this); + this.head = new ModelRenderer(this); + this.lid.setTextureOffset(0, 0).addBox(-8.0F, -16.0F, -8.0F, 16, 12, 16); + this.lid.setRotationPoint(0.0F, 24.0F, 0.0F); + this.base.setTextureOffset(0, 28).addBox(-8.0F, -8.0F, -8.0F, 16, 8, 16); + this.base.setRotationPoint(0.0F, 24.0F, 0.0F); + this.head.setTextureOffset(0, 52).addBox(-3.0F, 0.0F, -3.0F, 6, 6, 6); + this.head.setRotationPoint(0.0F, 12.0F, 0.0F); + } + + public int getModelVersion() + { + return 28; + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + public void setLivingAnimations(EntityLivingBase entitylivingbaseIn, float p_78086_2_, float p_78086_3_, float partialTickTime) + { + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn) + { + EntityShulker entityshulker = (EntityShulker)entityIn; + float f = ageInTicks - (float)entityshulker.ticksExisted; + float f1 = (0.5F + entityshulker.getClientPeekAmount(f)) * (float)Math.PI; + float f2 = -1.0F + MathHelper.sin(f1); + float f3 = 0.0F; + + if (f1 > (float)Math.PI) + { + f3 = MathHelper.sin(ageInTicks * 0.1F) * 0.7F; + } + + this.lid.setRotationPoint(0.0F, 16.0F + MathHelper.sin(f1) * 8.0F + f3, 0.0F); + + if (entityshulker.getClientPeekAmount(f) > 0.3F) + { + this.lid.rotateAngleY = f2 * f2 * f2 * f2 * (float)Math.PI * 0.125F; + } + else + { + this.lid.rotateAngleY = 0.0F; + } + + this.head.rotateAngleX = headPitch * 0.017453292F; + this.head.rotateAngleY = netHeadYaw * 0.017453292F; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) + { + this.base.render(scale); + this.lid.render(scale); + } +} diff --git a/src/main/java/net/minecraft/client/model/ModelShulkerBullet.java b/src/main/java/net/minecraft/client/model/ModelShulkerBullet.java new file mode 100644 index 0000000..ad7f4a0 --- /dev/null +++ b/src/main/java/net/minecraft/client/model/ModelShulkerBullet.java @@ -0,0 +1,40 @@ +package net.minecraft.client.model; + +import net.minecraft.entity.Entity; + +public class ModelShulkerBullet extends ModelBase +{ + public ModelRenderer renderer; + + public ModelShulkerBullet() + { + this.textureWidth = 64; + this.textureHeight = 32; + this.renderer = new ModelRenderer(this); + this.renderer.setTextureOffset(0, 0).addBox(-4.0F, -4.0F, -1.0F, 8, 8, 2, 0.0F); + this.renderer.setTextureOffset(0, 10).addBox(-1.0F, -4.0F, -4.0F, 2, 8, 8, 0.0F); + this.renderer.setTextureOffset(20, 0).addBox(-4.0F, -1.0F, -4.0F, 8, 2, 8, 0.0F); + this.renderer.setRotationPoint(0.0F, 0.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) + { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entityIn); + this.renderer.render(scale); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn) + { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn); + this.renderer.rotateAngleY = netHeadYaw * 0.017453292F; + this.renderer.rotateAngleX = headPitch * 0.017453292F; + } +} diff --git a/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java b/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java index 5cb35a6..e732cc1 100644 --- a/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java +++ b/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java @@ -93,6 +93,7 @@ import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.entity.projectile.EntityFishHook; import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.entity.projectile.EntityShulkerBullet; import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.entity.projectile.EntityWitherSkull; @@ -383,7 +384,7 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient { (double) packetIn.getSpeedX() / 8000.0D, (double) packetIn.getSpeedY() / 8000.0D, (double) packetIn.getSpeedZ() / 8000.0D); packetIn.func_149002_g(0); - } else if (packetIn.getType() == 64) { + } else if (packetIn.getType() == 64) { object = new EntitySmallFireball(this.clientWorldController, d0, d1, d2, (double) packetIn.getSpeedX() / 8000.0D, (double) packetIn.getSpeedY() / 8000.0D, (double) packetIn.getSpeedZ() / 8000.0D); @@ -393,7 +394,12 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient { (double) packetIn.getSpeedX() / 8000.0D, (double) packetIn.getSpeedY() / 8000.0D, (double) packetIn.getSpeedZ() / 8000.0D); packetIn.func_149002_g(0); - } else if (packetIn.getType() == 62) { + } else if (packetIn.getType() == 67) { + object = new EntityShulkerBullet(this.clientWorldController, d0, d1, d2, + (double) packetIn.getSpeedX() / 8000.0D, (double) packetIn.getSpeedY() / 8000.0D, + (double) packetIn.getSpeedZ() / 8000.0D); + packetIn.func_149002_g(0); + } else if (packetIn.getType() == 62) { object = new EntityEgg(this.clientWorldController, d0, d1, d2); } else if (packetIn.getType() == 73) { object = new EntityPotion(this.clientWorldController, d0, d1, d2, packetIn.func_149009_m()); diff --git a/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java b/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java index e5d9492..24cd0ab 100644 --- a/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java +++ b/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java @@ -25,6 +25,7 @@ import net.minecraft.client.model.ModelOcelot; import net.minecraft.client.model.ModelPig; import net.minecraft.client.model.ModelRabbit; import net.minecraft.client.model.ModelSheep2; +import net.minecraft.client.model.ModelShulker; import net.minecraft.client.model.ModelSlime; import net.minecraft.client.model.ModelSquid; import net.minecraft.client.model.ModelWolf; @@ -73,6 +74,7 @@ import net.minecraft.entity.monster.EntityGiantZombie; import net.minecraft.entity.monster.EntityGuardian; import net.minecraft.entity.monster.EntityIronGolem; import net.minecraft.entity.monster.EntityMagmaCube; +import net.minecraft.entity.monster.EntityShulker; import net.minecraft.entity.monster.EntityPigZombie; import net.minecraft.entity.monster.EntitySilverfish; import net.minecraft.entity.monster.EntitySkeleton; @@ -99,6 +101,7 @@ import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.entity.projectile.EntityFishHook; import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.entity.projectile.EntityShulkerBullet; import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.entity.projectile.EntityWitherSkull; @@ -198,6 +201,7 @@ public class RenderManager { this.entityRenderMap.put(EntityIronGolem.class, new RenderIronGolem(this)); this.entityRenderMap.put(EntityBat.class, new RenderBat(this)); this.entityRenderMap.put(EntityGuardian.class, new RenderGuardian(this)); + this.entityRenderMap.put(EntityShulker.class, new RenderShulker(this, new ModelShulker())); this.entityRenderMap.put(EntityDragon.class, new RenderDragon(this)); this.entityRenderMap.put(EntityEnderCrystal.class, new RenderEnderCrystal(this)); this.entityRenderMap.put(EntityWither.class, new RenderWither(this)); @@ -218,6 +222,7 @@ public class RenderManager { this.entityRenderMap.put(EntitySmallFireball.class, new RenderFireball(this, 0.5F)); this.entityRenderMap.put(EntityDragonFireball.class, new RenderDragonFireball(this)); this.entityRenderMap.put(EntityWitherSkull.class, new RenderWitherSkull(this)); + this.entityRenderMap.put(EntityShulkerBullet.class, new RenderShulkerBullet(this)); this.entityRenderMap.put(EntityItem.class, new RenderEntityItem(this, itemRendererIn)); this.entityRenderMap.put(EntityXPOrb.class, new RenderXPOrb(this)); this.entityRenderMap.put(EntityTNTPrimed.class, new RenderTNTPrimed(this)); diff --git a/src/main/java/net/minecraft/client/renderer/entity/RenderShulker.java b/src/main/java/net/minecraft/client/renderer/entity/RenderShulker.java new file mode 100644 index 0000000..8168b89 --- /dev/null +++ b/src/main/java/net/minecraft/client/renderer/entity/RenderShulker.java @@ -0,0 +1,197 @@ +package net.minecraft.client.renderer.entity; + +import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.ModelShulker; +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.entity.monster.EntityShulker; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class RenderShulker extends RenderLiving +{ + private static final ResourceLocation SHULKER_ENDERGOLEM_TEXTURE = new ResourceLocation("textures/entity/shulker/endergolem.png"); + private int modelVersion; + + public RenderShulker(RenderManager manager, ModelShulker p_i46550_2_) + { + super(manager, p_i46550_2_, 0.0F); + this.addLayer(new RenderShulker.HeadLayer()); + this.modelVersion = p_i46550_2_.getModelVersion(); + this.shadowSize = 0.0F; + } + + /** + * Renders the desired {@code T} type Entity. + */ + public void doRender(EntityShulker entity, double x, double y, double z, float entityYaw, float partialTicks) + { + if (this.modelVersion != ((ModelShulker)this.mainModel).getModelVersion()) + { + this.mainModel = new ModelShulker(); + this.modelVersion = ((ModelShulker)this.mainModel).getModelVersion(); + } + + int i = entity.getClientTeleportInterp(); + + if (i > 0 && entity.isAttachedToBlock()) + { + BlockPos blockpos = entity.getAttachmentPos(); + BlockPos blockpos1 = entity.getOldAttachPos(); + double d0 = (double)((float)i - partialTicks) / 6.0D; + d0 = d0 * d0; + double d1 = (double)(blockpos.getX() - blockpos1.getX()) * d0; + double d2 = (double)(blockpos.getY() - blockpos1.getY()) * d0; + double d3 = (double)(blockpos.getZ() - blockpos1.getZ()) * d0; + super.doRender(entity, x - d1, y - d2, z - d3, entityYaw, partialTicks); + } + else + { + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + } + + public boolean shouldRender(EntityShulker livingEntity, ICamera camera, double camX, double camY, double camZ) + { + if (super.shouldRender(livingEntity, camera, camX, camY, camZ)) + { + return true; + } + else + { + if (livingEntity.getClientTeleportInterp() > 0 && livingEntity.isAttachedToBlock()) + { + BlockPos blockpos = livingEntity.getOldAttachPos(); + BlockPos blockpos1 = livingEntity.getAttachmentPos(); + Vec3d vec3d = new Vec3d((double)blockpos1.getX(), (double)blockpos1.getY(), (double)blockpos1.getZ()); + Vec3d vec3d1 = new Vec3d((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ()); + + if (camera.isBoundingBoxInFrustum(new AxisAlignedBB(vec3d1.xCoord, vec3d1.yCoord, vec3d1.zCoord, vec3d.xCoord, vec3d.yCoord, vec3d.zCoord))) + { + return true; + } + } + + return false; + } + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(EntityShulker entity) + { + return SHULKER_ENDERGOLEM_TEXTURE; + } + + protected void rotateCorpse(EntityShulker entityLiving, float p_77043_2_, float p_77043_3_, float partialTicks) + { + super.rotateCorpse(entityLiving, p_77043_2_, p_77043_3_, partialTicks); + + switch (entityLiving.getAttachmentFacing()) + { + case DOWN: + default: + break; + + case EAST: + GlStateManager.translate(0.5F, 0.5F, 0.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); + break; + + case WEST: + GlStateManager.translate(-0.5F, 0.5F, 0.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(-90.0F, 0.0F, 0.0F, 1.0F); + break; + + case NORTH: + GlStateManager.translate(0.0F, 0.5F, -0.5F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + break; + + case SOUTH: + GlStateManager.translate(0.0F, 0.5F, 0.5F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + break; + + case UP: + GlStateManager.translate(0.0F, 1.0F, 0.0F); + GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); + } + } + + /** + * Allows the render to do state modifications necessary before the model is rendered. + */ + protected void preRenderCallback(EntityShulker entitylivingbaseIn, float partialTickTime) + { + float f = 0.999F; + GlStateManager.scale(0.999F, 0.999F, 0.999F); + } + + class HeadLayer implements LayerRenderer + { + private HeadLayer() + { + } + + public void doRenderLayer(EntityShulker entitylivingbaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) + { + GlStateManager.pushMatrix(); + + switch (entitylivingbaseIn.getAttachmentFacing()) + { + case DOWN: + default: + break; + + case EAST: + GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(1.0F, -1.0F, 0.0F); + GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F); + break; + + case WEST: + GlStateManager.rotate(-90.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(-1.0F, -1.0F, 0.0F); + GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F); + break; + + case NORTH: + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(0.0F, -1.0F, -1.0F); + break; + + case SOUTH: + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(0.0F, -1.0F, 1.0F); + break; + + case UP: + GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.translate(0.0F, -2.0F, 0.0F); + } + + ModelRenderer modelrenderer = ((ModelShulker)RenderShulker.this.getMainModel()).head; + modelrenderer.rotateAngleY = netHeadYaw * 0.017453292F; + modelrenderer.rotateAngleX = headPitch * 0.017453292F; + RenderShulker.this.bindTexture(RenderShulker.SHULKER_ENDERGOLEM_TEXTURE); + modelrenderer.render(scale); + GlStateManager.popMatrix(); + } + + public boolean shouldCombineTextures() + { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/client/renderer/entity/RenderShulkerBullet.java b/src/main/java/net/minecraft/client/renderer/entity/RenderShulkerBullet.java new file mode 100644 index 0000000..b54edd0 --- /dev/null +++ b/src/main/java/net/minecraft/client/renderer/entity/RenderShulkerBullet.java @@ -0,0 +1,70 @@ +package net.minecraft.client.renderer.entity; + +import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; +import net.minecraft.client.model.ModelShulkerBullet; +import net.minecraft.entity.projectile.EntityShulkerBullet; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; + +public class RenderShulkerBullet extends Render +{ + private static final ResourceLocation SHULKER_SPARK_TEXTURE = new ResourceLocation("textures/entity/shulker/spark.png"); + private final ModelShulkerBullet model = new ModelShulkerBullet(); + + public RenderShulkerBullet(RenderManager manager) + { + super(manager); + } + + private float rotLerp(float p_188347_1_, float p_188347_2_, float p_188347_3_) + { + float f; + + for (f = p_188347_2_ - p_188347_1_; f < -180.0F; f += 360.0F) + { + ; + } + + while (f >= 180.0F) + { + f -= 360.0F; + } + + return p_188347_1_ + p_188347_3_ * f; + } + + /** + * Renders the desired {@code T} type Entity. + */ + public void doRender(EntityShulkerBullet entity, double x, double y, double z, float entityYaw, float partialTicks) + { + GlStateManager.pushMatrix(); + float f = this.rotLerp(entity.prevRotationYaw, entity.rotationYaw, partialTicks); + float f1 = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks; + float f2 = (float)entity.ticksExisted + partialTicks; + GlStateManager.translate((float)x, (float)y + 0.15F, (float)z); + GlStateManager.rotate(MathHelper.sin(f2 * 0.1F) * 180.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(MathHelper.cos(f2 * 0.1F) * 180.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(MathHelper.sin(f2 * 0.15F) * 360.0F, 0.0F, 0.0F, 1.0F); + float f3 = 0.03125F; + GlStateManager.enableRescaleNormal(); + GlStateManager.scale(-1.0F, -1.0F, 1.0F); + this.bindEntityTexture(entity); + this.model.render(entity, 0.0F, 0.0F, 0.0F, f, f1, f3); + GlStateManager.enableBlend(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F); + GlStateManager.scale(1.5F, 1.5F, 1.5F); + this.model.render(entity, 0.0F, 0.0F, 0.0F, f, f1, f3); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(EntityShulkerBullet entity) + { + return SHULKER_SPARK_TEXTURE; + } +} diff --git a/src/main/java/net/minecraft/entity/DataWatcher.java b/src/main/java/net/minecraft/entity/DataWatcher.java index 5ec24c1..165f623 100644 --- a/src/main/java/net/minecraft/entity/DataWatcher.java +++ b/src/main/java/net/minecraft/entity/DataWatcher.java @@ -7,6 +7,7 @@ import java.util.Map; import org.apache.commons.lang3.ObjectUtils; +import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -337,6 +338,7 @@ public class DataWatcher { float f1 = buffer.readFloat(); float f2 = buffer.readFloat(); datawatcher$watchableobject = new DataWatcher.WatchableObject(i, j, new Rotations(f, f1, f2)); + break; } arraylist.add(datawatcher$watchableobject); @@ -346,7 +348,6 @@ public class DataWatcher { } public void updateWatchedObjectsFromList(List parList) { - for (int i = 0, l = parList.size(); i < l; ++i) { DataWatcher.WatchableObject datawatcher$watchableobject = parList.get(i); DataWatcher.WatchableObject datawatcher$watchableobject1 = (DataWatcher.WatchableObject) this.watchedObjects diff --git a/src/main/java/net/minecraft/entity/EntityList.java b/src/main/java/net/minecraft/entity/EntityList.java index 9f7f3c1..a88af16 100644 --- a/src/main/java/net/minecraft/entity/EntityList.java +++ b/src/main/java/net/minecraft/entity/EntityList.java @@ -46,6 +46,7 @@ import net.minecraft.entity.monster.EntityIronGolem; import net.minecraft.entity.monster.EntityMagmaCube; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntityShulker; import net.minecraft.entity.monster.EntitySilverfish; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySlime; @@ -71,6 +72,7 @@ import net.minecraft.entity.projectile.EntityDragonFireball; import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.entity.projectile.EntityShulkerBullet; import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.entity.projectile.EntityWitherSkull; @@ -176,6 +178,7 @@ public class EntityList { } } catch (Exception exception) { logger.error("Could not create entity", exception); + exception.printStackTrace(); } return entity; @@ -191,6 +194,7 @@ public class EntityList { } } catch (Exception exception) { logger.error("Could not create entity", exception); + exception.printStackTrace(); } return entity; @@ -222,6 +226,7 @@ public class EntityList { } } catch (Exception exception) { logger.error("Could not create entity", exception); + exception.printStackTrace(); } if (entity != null) { @@ -248,6 +253,7 @@ public class EntityList { } } catch (Exception exception) { logger.error("Could not create entity", exception); + exception.printStackTrace(); } if (entity == null) { @@ -353,6 +359,7 @@ public class EntityList { addMapping(EntityTNTPrimed.class, EntityTNTPrimed::new, "PrimedTnt", 20); addMapping(EntityFallingBlock.class, EntityFallingBlock::new, "FallingSand", 21); addMapping(EntityFireworkRocket.class, EntityFireworkRocket::new, "FireworksRocketEntity", 22); + addMapping(EntityShulkerBullet.class, EntityShulkerBullet::new, "ShulkerBullet", 25); addMapping(EntityDragonFireball.class, EntityDragonFireball::new, "DragonFireball", 26); addMapping(EntityArmorStand.class, EntityArmorStand::new, "ArmorStand", 30); addMapping(EntityBoat.class, EntityBoat::new, "Boat", 41); @@ -390,6 +397,7 @@ public class EntityList { addMapping(EntityWitch.class, EntityWitch::new, "Witch", 66, 3407872, 5349438); addMapping(EntityEndermite.class, EntityEndermite::new, "Endermite", 67, 1447446, 7237230); addMapping(EntityGuardian.class, EntityGuardian::new, "Guardian", 68, 5931634, 15826224); + addMapping(EntityShulker.class, EntityShulker::new, "Shulker", 69, 9725844, 5060690); addMapping(EntityPig.class, EntityPig::new, "Pig", 90, 15771042, 14377823); addMapping(EntitySheep.class, EntitySheep::new, "Sheep", 91, 15198183, 16758197); addMapping(EntityCow.class, EntityCow::new, "Cow", 92, 4470310, 10592673); diff --git a/src/main/java/net/minecraft/entity/EntityTracker.java b/src/main/java/net/minecraft/entity/EntityTracker.java index 974b90f..7b447f9 100644 --- a/src/main/java/net/minecraft/entity/EntityTracker.java +++ b/src/main/java/net/minecraft/entity/EntityTracker.java @@ -30,6 +30,7 @@ import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.entity.projectile.EntityFireball; import net.minecraft.entity.projectile.EntityFishHook; import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.entity.projectile.EntityShulkerBullet; import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.network.Packet; @@ -133,7 +134,9 @@ public class EntityTracker { this.addEntityToTracker(parEntity, 64, 3, true); } else if (parEntity instanceof EntityWither) { this.addEntityToTracker(parEntity, 80, 3, false); - } else if (parEntity instanceof EntityBat) { + } else if (parEntity instanceof EntityShulkerBullet) { + this.addEntityToTracker(parEntity, 80, 3, true); + } else if (parEntity instanceof EntityBat) { this.addEntityToTracker(parEntity, 80, 3, false); } else if (parEntity instanceof EntityDragon) { this.addEntityToTracker(parEntity, 160, 3, true); diff --git a/src/main/java/net/minecraft/entity/EntityTrackerEntry.java b/src/main/java/net/minecraft/entity/EntityTrackerEntry.java index cf8da9b..624e03e 100644 --- a/src/main/java/net/minecraft/entity/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/entity/EntityTrackerEntry.java @@ -31,6 +31,7 @@ import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.entity.projectile.EntityFireball; import net.minecraft.entity.projectile.EntityFishHook; import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.entity.projectile.EntityShulkerBullet; import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.entity.projectile.EntityWitherSkull; @@ -547,7 +548,13 @@ public class EntityTrackerEntry { s0epacketspawnobject2.setSpeedY((int) (entityfireball.accelerationY * 8000.0D)); s0epacketspawnobject2.setSpeedZ((int) (entityfireball.accelerationZ * 8000.0D)); return s0epacketspawnobject2; - } else if (this.trackedEntity instanceof EntityEgg) { + } else if (this.trackedEntity instanceof EntityShulkerBullet) { + S0EPacketSpawnObject spacketspawnobject1 = new S0EPacketSpawnObject(this.trackedEntity, 67, 0); + spacketspawnobject1.setSpeedX((int) (this.trackedEntity.motionX * 8000.0D)); + spacketspawnobject1.setSpeedY((int) (this.trackedEntity.motionY * 8000.0D)); + spacketspawnobject1.setSpeedZ((int) (this.trackedEntity.motionZ * 8000.0D)); + return spacketspawnobject1; + } else if (this.trackedEntity instanceof EntityEgg) { return new S0EPacketSpawnObject(this.trackedEntity, 62); } else if (this.trackedEntity instanceof EntityTNTPrimed) { return new S0EPacketSpawnObject(this.trackedEntity, 50); diff --git a/src/main/java/net/minecraft/entity/monster/EntityShulker.java b/src/main/java/net/minecraft/entity/monster/EntityShulker.java new file mode 100644 index 0000000..7a29305 --- /dev/null +++ b/src/main/java/net/minecraft/entity/monster/EntityShulker.java @@ -0,0 +1,754 @@ +package net.minecraft.entity.monster; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import java.util.List; +import javax.annotation.Nullable; + +import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; +import net.minecraft.block.Block; +import net.minecraft.block.BlockPistonBase; +import net.minecraft.block.BlockPistonExtension; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityBodyHelper; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.entity.projectile.EntityShulkerBullet; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; + +public class EntityShulker extends EntityGolem implements IMob +{ + private static final EaglercraftUUID COVERED_ARMOR_BONUS_ID = EaglercraftUUID.fromString("7E0292F2-9434-48D5-A29F-9583AF7DF27F"); + private static final AttributeModifier COVERED_ARMOR_BONUS_MODIFIER = (new AttributeModifier(COVERED_ARMOR_BONUS_ID, "Covered armor bonus", 20.0D, 0)).setSaved(false); + private float currentPeekAmount0; + private float currentPeekAmount; + private BlockPos currentAttachmentPosition; + private int clientSideTeleportInterpolation; + + public EntityShulker(World worldIn) + { + super(worldIn); + this.setSize(1.0F, 1.0F); + this.prevRenderYawOffset = 180.0F; + this.renderYawOffset = 180.0F; + this.isImmuneToFire = true; + this.currentAttachmentPosition = null; + this.experienceValue = 5; + } + + @Nullable + + /** + * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called + * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory + */ + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) + { + this.renderYawOffset = 180.0F; + this.prevRenderYawOffset = 180.0F; + this.rotationYaw = 180.0F; + this.prevRotationYaw = 180.0F; + this.rotationYawHead = 180.0F; + this.prevRotationYawHead = 180.0F; + return super.onInitialSpawn(difficulty, livingdata); + } + + protected void initEntityAI() + { + this.tasks.addTask(1, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(4, new EntityShulker.AIAttack()); + this.tasks.addTask(7, new EntityShulker.AIPeek()); + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true, new Class[0])); + this.targetTasks.addTask(2, new EntityShulker.AIAttackNearest(this)); + this.targetTasks.addTask(3, new EntityShulker.AIDefenseAttack(this)); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to + * prevent them from trampling crops + */ + protected boolean canTriggerWalking() + { + return false; + } + + /** + * Plays living's sound at its position + */ + public void playLivingSound() + { + if (!this.isClosed()) + { + super.playLivingSound(); + } + } + + protected String getDeathSound() + { + return "entity.shulker.death"; + } + + protected String getHurtSound() + { + return this.isClosed() ? "entity.shulker.hurt_closed" : "entity.shulker.hurt"; + } + + protected void entityInit() + { + super.entityInit(); + this.getDataWatcher().addObject(11, Integer.valueOf(EnumFacing.DOWN.getIndex())); + this.getDataWatcher().addObject(12, new BlockPos(0, 0, 0)); + this.getDataWatcher().addObject(13, Byte.valueOf((byte)0)); + this.getDataWatcher().addObject(14, Byte.valueOf((byte)0)); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); + } + + protected EntityBodyHelper createBodyHelper() + { + return new EntityShulker.BodyHelper(this); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.getDataWatcher().updateObject(11, Integer.valueOf(compound.getByte("AttachFace"))); + this.getDataWatcher().updateObject(13, Byte.valueOf(compound.getByte("Peek"))); + + if (compound.hasKey("APX")) { + int i = compound.getInteger("APX"); + int j = compound.getInteger("APY"); + int k = compound.getInteger("APZ"); + this.getDataWatcher().updateObject(12, new BlockPos(i, j, k)); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + } else { + this.getDataWatcher().updateObject(12, new BlockPos(0, 0, 0)); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)0)); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound compound) + { + super.writeEntityToNBT(compound); + compound.setByte("AttachFace", (byte)((Integer)this.getDataWatcher().getWatchableObjectInt(11)).intValue()); + compound.setByte("Peek", ((Byte)this.getDataWatcher().getWatchableObjectByte(13)).byteValue()); + BlockPos blockpos = this.getAttachmentPos(); + + if (blockpos != null) + { + compound.setInteger("APX", blockpos.getX()); + compound.setInteger("APY", blockpos.getY()); + compound.setInteger("APZ", blockpos.getZ()); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + super.onUpdate(); + BlockPos blockpos; + if (this.getDataWatcher().getWatchableObjectByte(13) == 1) { + blockpos = this.getDataWatcher().getWatchableObjectBlockPos(12); + } else { + blockpos = null; + } + + if (blockpos == null && !this.worldObj.isRemote) + { + blockpos = new BlockPos(this); + this.getDataWatcher().updateObject(12, blockpos); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + } + + if (!this.worldObj.isRemote) + { + IBlockState iblockstate = this.worldObj.getBlockState(blockpos); + + if (iblockstate.getBlock() != Blocks.air) + { + if (iblockstate.getBlock() == Blocks.piston_extension) + { + EnumFacing enumfacing = (EnumFacing)iblockstate.getValue(BlockPistonBase.FACING); + blockpos = blockpos.offset(enumfacing); + this.getDataWatcher().updateObject(12, blockpos); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + } + else if (iblockstate.getBlock() == Blocks.piston_head) + { + EnumFacing enumfacing3 = (EnumFacing)iblockstate.getValue(BlockPistonExtension.FACING); + blockpos = blockpos.offset(enumfacing3); + this.getDataWatcher().updateObject(12, blockpos); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + } + else + { + this.tryTeleportToNewPosition(); + } + } + + BlockPos blockpos1 = blockpos.offset(this.getAttachmentFacing()); + + if (!this.worldObj.isBlockNormalCube(blockpos1, false)) + { + boolean flag = false; + + for (EnumFacing enumfacing1 : EnumFacing.values()) + { + blockpos1 = blockpos.offset(enumfacing1); + + if (this.worldObj.isBlockNormalCube(blockpos1, false)) + { + this.getDataWatcher().updateObject(11, Integer.valueOf(enumfacing1.getIndex())); + flag = true; + break; + } + } + + if (!flag) + { + this.tryTeleportToNewPosition(); + } + } + + BlockPos blockpos2 = blockpos.offset(this.getAttachmentFacing().getOpposite()); + + if (this.worldObj.isBlockNormalCube(blockpos2, false)) + { + this.tryTeleportToNewPosition(); + } + } + + float f1 = (float)this.getPeekTick() * 0.01F; + this.currentPeekAmount0 = this.currentPeekAmount; + + if (this.currentPeekAmount > f1) + { + this.currentPeekAmount = MathHelper.clamp_float(this.currentPeekAmount - 0.05F, f1, 1.0F); + } + else if (this.currentPeekAmount < f1) + { + this.currentPeekAmount = MathHelper.clamp_float(this.currentPeekAmount + 0.05F, 0.0F, f1); + } + + if (blockpos != null) + { + if (this.worldObj.isRemote) + { + if (this.clientSideTeleportInterpolation > 0 && this.currentAttachmentPosition != null) + { + --this.clientSideTeleportInterpolation; + } + else + { + this.currentAttachmentPosition = blockpos; + } + } + + this.lastTickPosX = this.prevPosX = this.posX = (double)blockpos.getX() + 0.5D; + this.lastTickPosY = this.prevPosY = this.posY = (double)blockpos.getY(); + this.lastTickPosZ = this.prevPosZ = this.posZ = (double)blockpos.getZ() + 0.5D; + double d3 = 0.5D - (double)MathHelper.sin((0.5F + this.currentPeekAmount) * (float)Math.PI) * 0.5D; + double d4 = 0.5D - (double)MathHelper.sin((0.5F + this.currentPeekAmount0) * (float)Math.PI) * 0.5D; + double d5 = d3 - d4; + double d0 = 0.0D; + double d1 = 0.0D; + double d2 = 0.0D; + EnumFacing enumfacing2 = this.getAttachmentFacing(); + + switch (enumfacing2) + { + case DOWN: + default: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D, this.posY, this.posZ - 0.5D, this.posX + 0.5D, this.posY + 1.0D + d3, this.posZ + 0.5D)); + d1 = d5; + break; + + case UP: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D, this.posY - d3, this.posZ - 0.5D, this.posX + 0.5D, this.posY + 1.0D, this.posZ + 0.5D)); + d1 = -d5; + break; + + case NORTH: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D, this.posY, this.posZ - 0.5D, this.posX + 0.5D, this.posY + 1.0D, this.posZ + 0.5D + d3)); + d2 = d5; + break; + + case SOUTH: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D, this.posY, this.posZ - 0.5D - d3, this.posX + 0.5D, this.posY + 1.0D, this.posZ + 0.5D)); + d2 = -d5; + break; + + case WEST: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D, this.posY, this.posZ - 0.5D, this.posX + 0.5D + d3, this.posY + 1.0D, this.posZ + 0.5D)); + d0 = d5; + break; + + case EAST: + this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.5D - d3, this.posY, this.posZ - 0.5D, this.posX + 0.5D, this.posY + 1.0D, this.posZ + 0.5D)); + d0 = -d5; + } + + if (d5 > 0.0D) + { + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox()); + + if (!list.isEmpty()) + { + for (Entity entity : list) + { + if (!(entity instanceof EntityShulker) && !entity.noClip) + { + entity.moveEntity(d0, d1, d2); + } + } + } + } + } + } + + /** + * Sets the x,y,z of the entity from the given parameters. Also seems to set up a bounding box. + */ + public void setPosition(double x, double y, double z) + { + super.setPosition(x, y, z); + + if (this.dataWatcher != null && this.ticksExisted != 0) + { + Boolean blockPosExists = this.getDataWatcher().getWatchableObjectByte(13) == 1; + Optional optional = blockPosExists ? Optional.of(this.getDataWatcher().getWatchableObjectBlockPos(12)) : Optional.absent(); + Optional optional1 = Optional.of(new BlockPos(x, y, z)); + + if (!optional1.equals(optional)) + { + if (optional.isPresent()) + { + this.dataWatcher.updateObject(12, optional1.get()); + this.dataWatcher.updateObject(13, Byte.valueOf((byte)1)); + } else { + this.dataWatcher.updateObject(12, new BlockPos(0, 0, 0)); + this.dataWatcher.updateObject(13, Byte.valueOf((byte)0)); + } + this.isAirBorne = true; + } + } + } + + protected boolean tryTeleportToNewPosition() + { + if (!this.isAIDisabled() && this.isEntityAlive()) + { + BlockPos blockpos = new BlockPos(this); + + for (int i = 0; i < 5; ++i) + { + BlockPos blockpos1 = blockpos.add(8 - this.rand.nextInt(17), 8 - this.rand.nextInt(17), 8 - this.rand.nextInt(17)); + + if (blockpos1.getY() > 0 && this.worldObj.isAirBlock(blockpos1) && this.worldObj.isInsideBorder(this.worldObj.getWorldBorder(), this) && this.worldObj.getCollidingBoundingBoxes(this, new AxisAlignedBB(blockpos1)).isEmpty()) + { + boolean flag = false; + + for (EnumFacing enumfacing : EnumFacing.values()) + { + if (this.worldObj.isBlockNormalCube(blockpos1.offset(enumfacing), false)) + { + this.getDataWatcher().updateObject(11, Integer.valueOf(enumfacing.getIndex())); + flag = true; + break; + } + } + + if (flag) + { + this.playSound("entity.shulker.teleport", 1.0F, 1.0F); + this.getDataWatcher().updateObject(12, blockpos1); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + this.setAttackTarget((EntityLivingBase)null); + return true; + } + } + } + + return false; + } + else + { + return true; + } + } + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + super.onLivingUpdate(); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevRenderYawOffset = 180.0F; + this.renderYawOffset = 180.0F; + this.rotationYaw = 180.0F; + } + + public void onDataWatcherUpdate(int dataID) + { + if (dataID == 11 && this.worldObj.isRemote && !this.isRiding()) + { + BlockPos blockpos = this.getAttachmentPos(); + + if (blockpos != null) + { + if (this.currentAttachmentPosition == null) + { + this.currentAttachmentPosition = blockpos; + } + else + { + this.clientSideTeleportInterpolation = 6; + } + + this.lastTickPosX = this.prevPosX = this.posX = (double)blockpos.getX() + 0.5D; + this.lastTickPosY = this.prevPosY = this.posY = (double)blockpos.getY(); + this.lastTickPosZ = this.prevPosZ = this.posZ = (double)blockpos.getZ() + 0.5D; + } + } + + super.onDataWatcherUpdate(dataID); + } + + /** + * Set the position and rotation values directly without any clamping. + */ + public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport) + { + this.newPosRotationIncrements = 0; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource source, float amount) + { + if (this.isClosed()) + { + Entity entity = source.getSourceOfDamage(); + + if (entity instanceof EntityArrow) + { + return false; + } + } + + if (super.attackEntityFrom(source, amount)) + { + if ((double)this.getHealth() < (double)this.getMaxHealth() * 0.5D && this.rand.nextInt(4) == 0) + { + this.tryTeleportToNewPosition(); + } + + return true; + } + else + { + return false; + } + } + + private boolean isClosed() + { + return this.getPeekTick() == 0; + } + + @Nullable + + /** + * Returns the collision bounding box for this entity + */ + public AxisAlignedBB getCollisionBoundingBox() + { + return this.isEntityAlive() ? this.getEntityBoundingBox() : null; + } + + public EnumFacing getAttachmentFacing() + { + return EnumFacing.getFront(this.getDataWatcher().getWatchableObjectInt(11)); + } + + @Nullable + public BlockPos getAttachmentPos() { + return this.getDataWatcher().getWatchableObjectByte(13) == 1 ? this.getDataWatcher().getWatchableObjectBlockPos(12) : null; + } + + public void setAttachmentPos(@Nullable BlockPos pos) + { + if (pos != null) { + this.getDataWatcher().updateObject(12, pos); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)1)); + } else { + this.getDataWatcher().updateObject(12, new BlockPos(0, 0, 0)); + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)0)); + } + } + + public int getPeekTick() + { + return this.getDataWatcher().getWatchableObjectByte(13); + } + + /** + * Applies or removes armor modifier + */ + public void updateArmorModifier(int p_184691_1_) + { + if (!this.worldObj.isRemote) + { + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(COVERED_ARMOR_BONUS_MODIFIER); + + if (p_184691_1_ == 0) + { + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier(COVERED_ARMOR_BONUS_MODIFIER); + this.playSound("entity.shulker.close", 1.0F, 1.0F); + } + else + { + this.playSound("entity.shulker.open", 1.0F, 1.0F); + } + } + + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)p_184691_1_)); + } + + public float getClientPeekAmount(float p_184688_1_) + { + return this.currentPeekAmount0 + (this.currentPeekAmount - this.currentPeekAmount0) * p_184688_1_; + } + + public int getClientTeleportInterp() + { + return this.clientSideTeleportInterpolation; + } + + public BlockPos getOldAttachPos() + { + return this.currentAttachmentPosition; + } + + public float getEyeHeight() + { + return 0.5F; + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently + * use in wolves. + */ + public int getVerticalFaceSpeed() + { + return 180; + } + + public int getHorizontalFaceSpeed() + { + return 180; + } + + /** + * Applies a velocity to the entities, to push them away from eachother. + */ + public void applyEntityCollision(Entity entityIn) + { + } + + public float getCollisionBorderSize() + { + return 0.0F; + } + + public boolean isAttachedToBlock() + { + return this.currentAttachmentPosition != null && this.getAttachmentPos() != null; + } + + class AIAttack extends EntityAIBase + { + private int attackTime; + + public AIAttack() + { + this.setMutexBits(3); + } + + public boolean shouldExecute() + { + EntityLivingBase entitylivingbase = EntityShulker.this.getAttackTarget(); + return entitylivingbase != null && entitylivingbase.isEntityAlive() ? EntityShulker.this.worldObj.getDifficulty() != EnumDifficulty.PEACEFUL : false; + } + + public void startExecuting() + { + this.attackTime = 20; + EntityShulker.this.updateArmorModifier(100); + } + + public void resetTask() + { + EntityShulker.this.updateArmorModifier(0); + } + + public void updateTask() + { + if (EntityShulker.this.worldObj.getDifficulty() != EnumDifficulty.PEACEFUL) + { + --this.attackTime; + EntityLivingBase entitylivingbase = EntityShulker.this.getAttackTarget(); + EntityShulker.this.getLookHelper().setLookPositionWithEntity(entitylivingbase, 180.0F, 180.0F); + double d0 = EntityShulker.this.getDistanceSqToEntity(entitylivingbase); + + if (d0 < 400.0D) + { + if (this.attackTime <= 0) + { + this.attackTime = 20 + EntityShulker.this.rand.nextInt(10) * 20 / 2; + EntityShulkerBullet entityshulkerbullet = new EntityShulkerBullet(EntityShulker.this.worldObj, EntityShulker.this, entitylivingbase, EntityShulker.this.getAttachmentFacing().getAxis()); + EntityShulker.this.worldObj.spawnEntityInWorld(entityshulkerbullet); + EntityShulker.this.playSound("entity.shulker.shoot", 2.0F, (EntityShulker.this.rand.nextFloat() - EntityShulker.this.rand.nextFloat()) * 0.2F + 1.0F); + } + } + else + { + EntityShulker.this.setAttackTarget((EntityLivingBase)null); + } + + super.updateTask(); + } + } + } + + class AIAttackNearest extends EntityAINearestAttackableTarget + { + public AIAttackNearest(EntityShulker shulker) + { + super(shulker, EntityPlayer.class, true); + } + + public boolean shouldExecute() + { + return EntityShulker.this.worldObj.getDifficulty() == EnumDifficulty.PEACEFUL ? false : super.shouldExecute(); + } + + protected AxisAlignedBB getTargetableArea(double targetDistance) + { + EnumFacing enumfacing = ((EntityShulker)this.taskOwner).getAttachmentFacing(); + return enumfacing.getAxis() == EnumFacing.Axis.X ? this.taskOwner.getEntityBoundingBox().expand(4.0D, targetDistance, targetDistance) : (enumfacing.getAxis() == EnumFacing.Axis.Z ? this.taskOwner.getEntityBoundingBox().expand(targetDistance, targetDistance, 4.0D) : this.taskOwner.getEntityBoundingBox().expand(targetDistance, 4.0D, targetDistance)); + } + } + + static class AIDefenseAttack extends EntityAINearestAttackableTarget + { + public AIDefenseAttack(EntityShulker shulker) + { + super(shulker, EntityLivingBase.class, 10, true, false, new Predicate() + { + public boolean apply(@Nullable EntityLivingBase p_apply_1_) + { + return p_apply_1_ instanceof IMob; + } + }); + } + + public boolean shouldExecute() + { + return this.taskOwner.getTeam() == null ? false : super.shouldExecute(); + } + + protected AxisAlignedBB getTargetableArea(double targetDistance) + { + EnumFacing enumfacing = ((EntityShulker)this.taskOwner).getAttachmentFacing(); + return enumfacing.getAxis() == EnumFacing.Axis.X ? this.taskOwner.getEntityBoundingBox().expand(4.0D, targetDistance, targetDistance) : (enumfacing.getAxis() == EnumFacing.Axis.Z ? this.taskOwner.getEntityBoundingBox().expand(targetDistance, targetDistance, 4.0D) : this.taskOwner.getEntityBoundingBox().expand(targetDistance, 4.0D, targetDistance)); + } + } + + class AIPeek extends EntityAIBase + { + private int peekTime; + + private AIPeek() + { + } + + public boolean shouldExecute() + { + return EntityShulker.this.getAttackTarget() == null && EntityShulker.this.rand.nextInt(40) == 0; + } + + public boolean continueExecuting() + { + return EntityShulker.this.getAttackTarget() == null && this.peekTime > 0; + } + + public void startExecuting() + { + this.peekTime = 20 * (1 + EntityShulker.this.rand.nextInt(3)); + EntityShulker.this.updateArmorModifier(30); + } + + public void resetTask() + { + if (EntityShulker.this.getAttackTarget() == null) + { + EntityShulker.this.updateArmorModifier(0); + } + } + + public void updateTask() + { + --this.peekTime; + } + } + + class BodyHelper extends EntityBodyHelper + { + public BodyHelper(EntityLivingBase p_i47062_2_) + { + super(p_i47062_2_); + } + + public void updateRenderAngles() + { + } + } +} diff --git a/src/main/java/net/minecraft/entity/projectile/EntityShulkerBullet.java b/src/main/java/net/minecraft/entity/projectile/EntityShulkerBullet.java new file mode 100644 index 0000000..eb20c17 --- /dev/null +++ b/src/main/java/net/minecraft/entity/projectile/EntityShulkerBullet.java @@ -0,0 +1,434 @@ +package net.minecraft.entity.projectile; + +import com.google.common.collect.Lists; +import java.util.List; +import javax.annotation.Nullable; + +import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +public class EntityShulkerBullet extends Entity +{ + private EntityLivingBase owner; + private Entity target; + @Nullable + private EnumFacing direction; + private int steps; + private double targetDeltaX; + private double targetDeltaY; + private double targetDeltaZ; + @Nullable + private EaglercraftUUID ownerUniqueId; + private BlockPos ownerBlockPos; + @Nullable + private EaglercraftUUID targetUniqueId; + private BlockPos targetBlockPos; + + public EntityShulkerBullet(World worldIn) + { + super(worldIn); + this.setSize(0.3125F, 0.3125F); + this.noClip = true; + } + + public EntityShulkerBullet(World worldIn, double x, double y, double z, double motionXIn, double motionYIn, double motionZIn) + { + this(worldIn); + this.setLocationAndAngles(x, y, z, this.rotationYaw, this.rotationPitch); + this.motionX = motionXIn; + this.motionY = motionYIn; + this.motionZ = motionZIn; + } + + public EntityShulkerBullet(World worldIn, EntityLivingBase ownerIn, Entity targetIn, EnumFacing.Axis p_i46772_4_) + { + this(worldIn); + this.owner = ownerIn; + BlockPos blockpos = new BlockPos(ownerIn); + double d0 = (double)blockpos.getX() + 0.5D; + double d1 = (double)blockpos.getY() + 0.5D; + double d2 = (double)blockpos.getZ() + 0.5D; + this.setLocationAndAngles(d0, d1, d2, this.rotationYaw, this.rotationPitch); + this.target = targetIn; + this.direction = EnumFacing.UP; + this.selectNextMoveDirection(p_i46772_4_); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound compound) + { + if (this.owner != null) + { + BlockPos blockpos = new BlockPos(this.owner); + NBTTagCompound nbttagcompound = NBTUtil.createUUIDTag(this.owner.getUniqueID()); + nbttagcompound.setInteger("X", blockpos.getX()); + nbttagcompound.setInteger("Y", blockpos.getY()); + nbttagcompound.setInteger("Z", blockpos.getZ()); + compound.setTag("Owner", nbttagcompound); + } + + if (this.target != null) + { + BlockPos blockpos1 = new BlockPos(this.target); + NBTTagCompound nbttagcompound1 = NBTUtil.createUUIDTag(this.target.getUniqueID()); + nbttagcompound1.setInteger("X", blockpos1.getX()); + nbttagcompound1.setInteger("Y", blockpos1.getY()); + nbttagcompound1.setInteger("Z", blockpos1.getZ()); + compound.setTag("Target", nbttagcompound1); + } + + if (this.direction != null) + { + compound.setInteger("Dir", this.direction.getIndex()); + } + + compound.setInteger("Steps", this.steps); + compound.setDouble("TXD", this.targetDeltaX); + compound.setDouble("TYD", this.targetDeltaY); + compound.setDouble("TZD", this.targetDeltaZ); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound compound) + { + this.steps = compound.getInteger("Steps"); + this.targetDeltaX = compound.getDouble("TXD"); + this.targetDeltaY = compound.getDouble("TYD"); + this.targetDeltaZ = compound.getDouble("TZD"); + + if (compound.hasKey("Dir", 99)) + { + this.direction = EnumFacing.getFront(compound.getInteger("Dir")); + } + + if (compound.hasKey("Owner", 10)) + { + NBTTagCompound nbttagcompound = compound.getCompoundTag("Owner"); + this.ownerUniqueId = NBTUtil.getUUIDFromTag(nbttagcompound); + this.ownerBlockPos = new BlockPos(nbttagcompound.getInteger("X"), nbttagcompound.getInteger("Y"), nbttagcompound.getInteger("Z")); + } + + if (compound.hasKey("Target", 10)) + { + NBTTagCompound nbttagcompound1 = compound.getCompoundTag("Target"); + this.targetUniqueId = NBTUtil.getUUIDFromTag(nbttagcompound1); + this.targetBlockPos = new BlockPos(nbttagcompound1.getInteger("X"), nbttagcompound1.getInteger("Y"), nbttagcompound1.getInteger("Z")); + } + } + + protected void entityInit() + { + } + + private void setDirection(@Nullable EnumFacing directionIn) + { + this.direction = directionIn; + } + + private void selectNextMoveDirection(@Nullable EnumFacing.Axis p_184569_1_) + { + double d0 = 0.5D; + BlockPos blockpos; + + if (this.target == null) + { + blockpos = (new BlockPos(this)).down(); + } + else + { + d0 = (double)this.target.height * 0.5D; + blockpos = new BlockPos(this.target.posX, this.target.posY + d0, this.target.posZ); + } + + double d1 = (double)blockpos.getX() + 0.5D; + double d2 = (double)blockpos.getY() + d0; + double d3 = (double)blockpos.getZ() + 0.5D; + EnumFacing enumfacing = null; + + if (blockpos.distanceSqToCenter(this.posX, this.posY, this.posZ) >= 4.0D) + { + BlockPos blockpos1 = new BlockPos(this); + List list = Lists.newArrayList(); + + if (p_184569_1_ != EnumFacing.Axis.X) + { + if (blockpos1.getX() < blockpos.getX() && this.worldObj.isAirBlock(blockpos1.east())) + { + list.add(EnumFacing.EAST); + } + else if (blockpos1.getX() > blockpos.getX() && this.worldObj.isAirBlock(blockpos1.west())) + { + list.add(EnumFacing.WEST); + } + } + + if (p_184569_1_ != EnumFacing.Axis.Y) + { + if (blockpos1.getY() < blockpos.getY() && this.worldObj.isAirBlock(blockpos1.up())) + { + list.add(EnumFacing.UP); + } + else if (blockpos1.getY() > blockpos.getY() && this.worldObj.isAirBlock(blockpos1.down())) + { + list.add(EnumFacing.DOWN); + } + } + + if (p_184569_1_ != EnumFacing.Axis.Z) + { + if (blockpos1.getZ() < blockpos.getZ() && this.worldObj.isAirBlock(blockpos1.south())) + { + list.add(EnumFacing.SOUTH); + } + else if (blockpos1.getZ() > blockpos.getZ() && this.worldObj.isAirBlock(blockpos1.north())) + { + list.add(EnumFacing.NORTH); + } + } + + enumfacing = EnumFacing.random(this.rand); + + if (list.isEmpty()) + { + for (int i = 5; !this.worldObj.isAirBlock(blockpos1.offset(enumfacing)) && i > 0; --i) + { + enumfacing = EnumFacing.random(this.rand); + } + } + else + { + enumfacing = (EnumFacing)list.get(this.rand.nextInt(list.size())); + } + + d1 = this.posX + (double)enumfacing.getFrontOffsetX(); + d2 = this.posY + (double)enumfacing.getFrontOffsetY(); + d3 = this.posZ + (double)enumfacing.getFrontOffsetZ(); + } + + this.setDirection(enumfacing); + double d6 = d1 - this.posX; + double d7 = d2 - this.posY; + double d4 = d3 - this.posZ; + double d5 = (double)MathHelper.sqrt_double(d6 * d6 + d7 * d7 + d4 * d4); + + if (d5 == 0.0D) + { + this.targetDeltaX = 0.0D; + this.targetDeltaY = 0.0D; + this.targetDeltaZ = 0.0D; + } + else + { + this.targetDeltaX = d6 / d5 * 0.15D; + this.targetDeltaY = d7 / d5 * 0.15D; + this.targetDeltaZ = d4 / d5 * 0.15D; + } + + this.isAirBorne = true; + this.steps = 10 + this.rand.nextInt(5) * 10; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + if (!this.worldObj.isRemote && this.worldObj.getDifficulty() == EnumDifficulty.PEACEFUL) + { + this.setDead(); + } + else + { + super.onUpdate(); + + if (!this.worldObj.isRemote) + { + if (this.target == null && this.targetUniqueId != null) + { + for (EntityLivingBase entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(this.targetBlockPos.add(-2, -2, -2), this.targetBlockPos.add(2, 2, 2)))) + { + if (entitylivingbase.getUniqueID().equals(this.targetUniqueId)) + { + this.target = entitylivingbase; + break; + } + } + + this.targetUniqueId = null; + } + + if (this.owner == null && this.ownerUniqueId != null) + { + for (EntityLivingBase entitylivingbase1 : this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(this.ownerBlockPos.add(-2, -2, -2), this.ownerBlockPos.add(2, 2, 2)))) + { + if (entitylivingbase1.getUniqueID().equals(this.ownerUniqueId)) + { + this.owner = entitylivingbase1; + break; + } + } + + this.ownerUniqueId = null; + } + + if (this.target == null || !this.target.isEntityAlive() || this.target instanceof EntityPlayer && ((EntityPlayer)this.target).isSpectator()) + { + this.motionY -= 0.04D; + } + else + { + this.targetDeltaX = MathHelper.clamp_double(this.targetDeltaX * 1.025D, -1.0D, 1.0D); + this.targetDeltaY = MathHelper.clamp_double(this.targetDeltaY * 1.025D, -1.0D, 1.0D); + this.targetDeltaZ = MathHelper.clamp_double(this.targetDeltaZ * 1.025D, -1.0D, 1.0D); + this.motionX += (this.targetDeltaX - this.motionX) * 0.2D; + this.motionY += (this.targetDeltaY - this.motionY) * 0.2D; + this.motionZ += (this.targetDeltaZ - this.motionZ) * 0.2D; + } + + RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, false, this.owner); + + if (raytraceresult != null) + { + this.bulletHit(raytraceresult); + } + } + + this.setPosition(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + ProjectileHelper.rotateTowardsMovement(this, 0.5F); + + if (this.worldObj.isRemote) + { + this.worldObj.spawnParticle(EnumParticleTypes.END_ROD, this.posX - this.motionX, this.posY - this.motionY + 0.15D, this.posZ - this.motionZ, 0.0D, 0.0D, 0.0D, new int[0]); + } + else if (this.target != null && !this.target.isDead) + { + if (this.steps > 0) + { + --this.steps; + + if (this.steps == 0) + { + this.selectNextMoveDirection(this.direction == null ? null : this.direction.getAxis()); + } + } + + if (this.direction != null) + { + BlockPos blockpos = new BlockPos(this); + EnumFacing.Axis enumfacing$axis = this.direction.getAxis(); + + if (this.worldObj.isBlockNormalCube(blockpos.offset(this.direction), false)) + { + this.selectNextMoveDirection(enumfacing$axis); + } + else + { + BlockPos blockpos1 = new BlockPos(this.target); + + if (enumfacing$axis == EnumFacing.Axis.X && blockpos.getX() == blockpos1.getX() || enumfacing$axis == EnumFacing.Axis.Z && blockpos.getZ() == blockpos1.getZ() || enumfacing$axis == EnumFacing.Axis.Y && blockpos.getY() == blockpos1.getY()) + { + this.selectNextMoveDirection(enumfacing$axis); + } + } + } + } + } + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. + */ + public boolean isBurning() + { + return false; + } + + /** + * Checks if the entity is in range to render. + */ + public boolean isInRangeToRenderDist(double distance) + { + return distance < 16384.0D; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float partialTicks) + { + return 1.0F; + } + + public int getBrightnessForRender(float partialTicks) + { + return 15728880; + } + + protected void bulletHit(RayTraceResult result) + { + if (result.entityHit == null) + { + ((WorldServer)this.worldObj).spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 2, 0.2D, 0.2D, 0.2D, 0.0D, new int[0]); + this.playSound("entity.shulker_bullet.hit", 1.0F, 1.0F); + } + else + { + boolean flag = result.entityHit.attackEntityFrom(DamageSource.causeIndirectDamage(this, this.owner).setProjectile(), 4.0F); + + if (flag) + { + this.applyEnchantments(this.owner, result.entityHit); + + if (result.entityHit instanceof EntityLivingBase) + { + ((EntityLivingBase)result.entityHit).addPotionEffect(new PotionEffect(Potion.levitation.getId(), 200)); + } + } + } + + this.setDead(); + } + + /** + * Returns true if other Entities should be prevented from moving through this Entity. + */ + public boolean canBeCollidedWith() + { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource source, float amount) + { + if (!this.worldObj.isRemote) + { + this.playSound("SoundEvents.ENTITY_SHULKER_BULLET_HURT", 1.0F, 1.0F); + ((WorldServer)this.worldObj).spawnParticle(EnumParticleTypes.CRIT, this.posX, this.posY, this.posZ, 15, 0.2D, 0.2D, 0.2D, 0.0D, new int[0]); + this.setDead(); + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/entity/projectile/ProjectileHelper.java b/src/main/java/net/minecraft/entity/projectile/ProjectileHelper.java new file mode 100644 index 0000000..b8c2a29 --- /dev/null +++ b/src/main/java/net/minecraft/entity/projectile/ProjectileHelper.java @@ -0,0 +1,99 @@ +package net.minecraft.entity.projectile; + +import java.util.List; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public final class ProjectileHelper +{ + public static RayTraceResult forwardsRaycast(Entity p_188802_0_, boolean p_188802_1_, boolean p_188802_2_, Entity p_188802_3_) + { + double d0 = p_188802_0_.posX; + double d1 = p_188802_0_.posY; + double d2 = p_188802_0_.posZ; + double d3 = p_188802_0_.motionX; + double d4 = p_188802_0_.motionY; + double d5 = p_188802_0_.motionZ; + World world = p_188802_0_.worldObj; + Vec3d vec3d = new Vec3d(d0, d1, d2); + Vec3d vec3d1 = new Vec3d(d0 + d3, d1 + d4, d2 + d5); + RayTraceResult raytraceresult = world.rayTraceBlocks(vec3d, vec3d1, false, true, false); + + if (p_188802_1_) + { + if (raytraceresult != null) + { + vec3d1 = new Vec3d(raytraceresult.hitVec.xCoord, raytraceresult.hitVec.yCoord, raytraceresult.hitVec.zCoord); + } + + Entity entity = null; + List list = world.getEntitiesWithinAABBExcludingEntity(p_188802_0_, p_188802_0_.getEntityBoundingBox().addCoord(d3, d4, d5).expandXyz(1.0D)); + double d6 = 0.0D; + + for (int i = 0; i < list.size(); ++i) + { + Entity entity1 = (Entity)list.get(i); + + if (entity1.canBeCollidedWith() && (p_188802_2_ || !entity1.isEntityEqual(p_188802_3_)) && !entity1.noClip) + { + AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().expandXyz(0.30000001192092896D); + RayTraceResult raytraceresult1 = axisalignedbb.calculateIntercept(vec3d, vec3d1); + + if (raytraceresult1 != null) + { + double d7 = vec3d.squareDistanceTo(raytraceresult1.hitVec); + + if (d7 < d6 || d6 == 0.0D) + { + entity = entity1; + d6 = d7; + } + } + } + } + + if (entity != null) + { + raytraceresult = new RayTraceResult(entity); + } + } + + return raytraceresult; + } + + public static final void rotateTowardsMovement(Entity p_188803_0_, float p_188803_1_) + { + double d0 = p_188803_0_.motionX; + double d1 = p_188803_0_.motionY; + double d2 = p_188803_0_.motionZ; + float f = MathHelper.sqrt_double(d0 * d0 + d2 * d2); + p_188803_0_.rotationYaw = (float)(MathHelper.atan2(d2, d0) * (180D / Math.PI)) + 90.0F; + + for (p_188803_0_.rotationPitch = (float)(MathHelper.atan2((double)f, d1) * (180D / Math.PI)) - 90.0F; p_188803_0_.rotationPitch - p_188803_0_.prevRotationPitch < -180.0F; p_188803_0_.prevRotationPitch -= 360.0F) + { + ; + } + + while (p_188803_0_.rotationPitch - p_188803_0_.prevRotationPitch >= 180.0F) + { + p_188803_0_.prevRotationPitch += 360.0F; + } + + while (p_188803_0_.rotationYaw - p_188803_0_.prevRotationYaw < -180.0F) + { + p_188803_0_.prevRotationYaw -= 360.0F; + } + + while (p_188803_0_.rotationYaw - p_188803_0_.prevRotationYaw >= 180.0F) + { + p_188803_0_.prevRotationYaw += 360.0F; + } + + p_188803_0_.rotationPitch = p_188803_0_.prevRotationPitch + (p_188803_0_.rotationPitch - p_188803_0_.prevRotationPitch) * p_188803_1_; + p_188803_0_.rotationYaw = p_188803_0_.prevRotationYaw + (p_188803_0_.rotationYaw - p_188803_0_.prevRotationYaw) * p_188803_1_; + } +} diff --git a/src/main/java/net/minecraft/nbt/NBTUtil.java b/src/main/java/net/minecraft/nbt/NBTUtil.java index 9a87c9b..c09542f 100644 --- a/src/main/java/net/minecraft/nbt/NBTUtil.java +++ b/src/main/java/net/minecraft/nbt/NBTUtil.java @@ -90,6 +90,22 @@ public final class NBTUtil { } } + public static NBTTagCompound createUUIDTag(EaglercraftUUID uuid) + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + nbttagcompound.setLong("M", uuid.getMostSignificantBits()); + nbttagcompound.setLong("L", uuid.getLeastSignificantBits()); + return nbttagcompound; + } + + /** + * Reads a UUID from the passed NBTTagCompound. + */ + public static EaglercraftUUID getUUIDFromTag(NBTTagCompound tag) + { + return new EaglercraftUUID(tag.getLong("M"), tag.getLong("L")); + } + /** * + * Writes a GameProfile to an NBTTagCompound. diff --git a/src/main/java/net/minecraft/util/DamageSource.java b/src/main/java/net/minecraft/util/DamageSource.java index 0f23a41..c9f8c20 100644 --- a/src/main/java/net/minecraft/util/DamageSource.java +++ b/src/main/java/net/minecraft/util/DamageSource.java @@ -109,6 +109,11 @@ public class DamageSource { .setMagicDamage(); } + public static DamageSource causeIndirectDamage(Entity source, EntityLivingBase indirectEntityIn) + { + return new EntityDamageSourceIndirect("mob", source, indirectEntityIn); + } + /** * + * Returns the EntityDamageSource of the Thorns enchantment diff --git a/src/main/java/net/minecraft/util/EntitySelectors.java b/src/main/java/net/minecraft/util/EntitySelectors.java index 76322d7..7305fa0 100644 --- a/src/main/java/net/minecraft/util/EntitySelectors.java +++ b/src/main/java/net/minecraft/util/EntitySelectors.java @@ -1,11 +1,14 @@ package net.minecraft.util; +import javax.annotation.Nullable; + import com.google.common.base.Predicate; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.entity.monster.EntityShulker; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -71,6 +74,14 @@ public final class EntitySelectors { } }; + public static final Predicate IS_SHULKER = new Predicate() + { + public boolean apply(@Nullable Entity p_apply_1_) + { + return p_apply_1_ instanceof EntityShulker && p_apply_1_.isEntityAlive(); + } + }; + public static class ArmoredMob implements Predicate { private final ItemStack armor; diff --git a/src/main/java/net/minecraft/util/math/AxisAlignedBB.java b/src/main/java/net/minecraft/util/math/AxisAlignedBB.java index 45f825c..d939459 100644 --- a/src/main/java/net/minecraft/util/math/AxisAlignedBB.java +++ b/src/main/java/net/minecraft/util/math/AxisAlignedBB.java @@ -57,6 +57,11 @@ public class AxisAlignedBB { this.maxZ = (double) pos2.getZ(); } + public AxisAlignedBB(BlockPos pos) + { + this((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)(pos.getX() + 1), (double)(pos.getY() + 1), (double)(pos.getZ() + 1)); + } + /** * + * Adds the coordinates to the bounding box extending it if the @@ -105,6 +110,10 @@ public class AxisAlignedBB { return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); } + public AxisAlignedBB expandXyz(double value) { + return this.expand(value, value, value); + } + public AxisAlignedBB union(AxisAlignedBB other) { double d0 = Math.min(this.minX, other.minX); double d1 = Math.min(this.minY, other.minY); diff --git a/src/main/java/net/minecraft/util/math/MathHelper.java b/src/main/java/net/minecraft/util/math/MathHelper.java index 7b200eb..283f138 100644 --- a/src/main/java/net/minecraft/util/math/MathHelper.java +++ b/src/main/java/net/minecraft/util/math/MathHelper.java @@ -73,6 +73,20 @@ public class MathHelper { return (float) FastMath.sqrt(value); } + public static double atan2(double p_181159_0_, double p_181159_2_) { + return FastMath.atan2(p_181159_0_, p_181159_2_); + } + + public static double fastInvSqrt(double p_181161_0_) + { + double d0 = 0.5D * p_181161_0_; + long i = Double.doubleToRawLongBits(p_181161_0_); + i = 6910469410427058090L - (i >> 1); + p_181161_0_ = Double.longBitsToDouble(i); + p_181161_0_ = p_181161_0_ * (1.5D - d0 * p_181161_0_ * p_181161_0_); + return p_181161_0_; + } + // silly thing from quake3 public static float Q_rsqrt(float value) { int i = Float.floatToRawIntBits(value);