idk if this works
This commit is contained in:
parent
163f6ae7d9
commit
7027b6d40a
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 847 B |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 847 B |
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<EntityShulker>
|
||||
{
|
||||
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<EntityShulker>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<EntityShulkerBullet>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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<DataWatcher.WatchableObject> 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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Entity> 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<BlockPos> optional = blockPosExists ? Optional.of(this.getDataWatcher().getWatchableObjectBlockPos(12)) : Optional.<BlockPos>absent();
|
||||
Optional<BlockPos> optional1 = Optional.<BlockPos>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<EntityPlayer>
|
||||
{
|
||||
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<EntityLivingBase>
|
||||
{
|
||||
public AIDefenseAttack(EntityShulker shulker)
|
||||
{
|
||||
super(shulker, EntityLivingBase.class, 10, true, false, new Predicate<EntityLivingBase>()
|
||||
{
|
||||
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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<EnumFacing> list = Lists.<EnumFacing>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;
|
||||
}
|
||||
}
|
|
@ -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<Entity> 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_;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Entity> IS_SHULKER = new Predicate<Entity>()
|
||||
{
|
||||
public boolean apply(@Nullable Entity p_apply_1_)
|
||||
{
|
||||
return p_apply_1_ instanceof EntityShulker && p_apply_1_.isEntityAlive();
|
||||
}
|
||||
};
|
||||
|
||||
public static class ArmoredMob implements Predicate<Entity> {
|
||||
private final ItemStack armor;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue