package minefantasy.mf2.entity; import java.util.Iterator; import java.util.List; import minefantasy.mf2.item.gadget.EnumCasingType; import minefantasy.mf2.item.gadget.EnumExplosiveType; import minefantasy.mf2.item.gadget.EnumFuseType; import minefantasy.mf2.item.gadget.EnumPowderType; import minefantasy.mf2.item.list.ToolListMF; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; import net.minecraft.world.World; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class EntityMine extends Entity { /** How long the fuse is */ public int fuse; private EntityLivingBase thrower; public EntityMine(World world) { super(world); this.preventEntitySpawning = true; this.setSize(0.5F, 0.25F); this.yOffset = this.height / 2.0F; } public EntityMine(World world, EntityLivingBase thrower) { this(world); this.thrower = thrower; this.fuse = 40; this.setLocationAndAngles(thrower.posX, thrower.posY + thrower.getEyeHeight(), thrower.posZ, thrower.rotationYaw, thrower.rotationPitch); this.posX -= MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F; this.posY -= 0.10000000149011612D; this.posZ -= MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F; this.setPosition(this.posX, this.posY, this.posZ); float f = 0.4F; this.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * f; this.motionZ = MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * f; this.motionY = -MathHelper.sin((this.rotationPitch + this.getThrownOffset()) / 180.0F * (float)Math.PI) * f; this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.getThrownForce(), 1.0F); this.prevPosX = posX; this.prevPosY = posY; this.prevPosZ = posZ; } @Override public boolean interactFirst(EntityPlayer user) { if(user.isSneaking()) { //DISARM setDead(); user.swingItem(); if(!worldObj.isRemote) { ItemStack item = ToolListMF.mine_custom.createMine(getCasing(), getFilling(), getFuse(), getPowder(), 1); if(!user.inventory.addItemStackToInventory(item)) { this.entityDropItem(item, 0.0F); } } } return super.interactFirst(user); } public void setThrowableHeading(double x, double y, double z, float offset, float force) { float f2 = MathHelper.sqrt_double(x * x + y * y + z * z); x /= f2; y /= f2; z /= f2; x += this.rand.nextGaussian() * 0.007499999832361937D * force; y += this.rand.nextGaussian() * 0.007499999832361937D * force; z += this.rand.nextGaussian() * 0.007499999832361937D * force; x *= offset; y *= offset; z *= offset; this.motionX = x; this.motionY = y; this.motionZ = z; float f3 = MathHelper.sqrt_double(x * x + z * z); this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(x, z) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(y, f3) * 180.0D / Math.PI); } protected float getThrownOffset() { return 0.0F; } protected float getThrownForce() { return 0.5F; } @Override protected void entityInit() { dataWatcher.addObject(typeId, (byte)0); dataWatcher.addObject(typeId+1, (byte)0); dataWatcher.addObject(typeId+2, (byte)0); dataWatcher.addObject(typeId+3, (byte)0); } /** * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to * prevent them from trampling crops */ @Override protected boolean canTriggerWalking() { return false; } /** * Returns true if other Entities should be prevented from moving through this Entity. */ @Override public boolean canBeCollidedWith() { return !this.isDead; } /** * Called to update the entity's position/logic. */ @Override public void onUpdate() { this.prevPosX = this.posX; this.prevPosY = this.posY; this.prevPosZ = this.posZ; this.motionY -= (0.03999999910593033D * getCase().weightModifier); this.moveEntity(this.motionX, this.motionY, this.motionZ); this.motionX *= 0.9800000190734863D; this.motionY *= 0.9800000190734863D; this.motionZ *= 0.9800000190734863D; if (this.onGround) { this.motionX = 0; this.motionZ = 0; this.motionY *= -0.99D; } if(fuse > 0) { --fuse; } double radius = Math.max(1.0D, getRangeOfBlast()-1.5D); if(ticksExisted % 5 == 0) { List<EntityLivingBase> list = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, boundingBox.expand(radius*2, radius, radius*2)); if (fuse == 0 && !list.isEmpty()) { boolean detonate = false; Iterator i = list.iterator(); while(i.hasNext()) { EntityLivingBase e = (EntityLivingBase) i.next(); if(e.getDistanceToEntity(this) < radius) { detonate = true; break; } } if(detonate) { worldObj.playSoundEffect(posX, posY, posZ, "game.tnt.primed", 1.0F, 0.75F); --fuse; } } } if(fuse < 0) { fuse --; if(fuse < -10) { this.setDead(); if (!this.worldObj.isRemote) { this.explode(); } } } } private void explode2() { float power = 5.0F; this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, power, false); } /** * (abstract) Protected helper method to write subclass entity data to NBT. */ @Override protected void writeEntityToNBT(NBTTagCompound nbt) { nbt.setByte("Fuse", (byte)this.fuse); } /** * (abstract) Protected helper method to read subclass entity data from NBT. */ @Override protected void readEntityFromNBT(NBTTagCompound nbt) { this.fuse = nbt.getByte("Fuse"); } @Override @SideOnly(Side.CLIENT) public float getShadowSize() { return 0.25F; } /** * returns null or the entityliving it was placed or ignited by */ public EntityLivingBase getTntPlacedBy() { return this.thrower; } public void explode() { worldObj.playSoundAtEntity(this, "random.explode", 0.3F, 10F - 5F); worldObj.createExplosion(this, posX, posY, posZ, 0, false); if (!this.worldObj.isRemote) { double area = getRangeOfBlast()*2D* getPowderType().rangeModifier; AxisAlignedBB var3 = this.boundingBox.expand(area, area/2, area); List var4 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, var3); if (var4 != null && !var4.isEmpty()) { Iterator splashDamage = var4.iterator(); while (splashDamage.hasNext()) { Entity entityHit = (Entity)splashDamage.next(); double distanceToEntity = this.getDistanceToEntity(entityHit); double radius = getRangeOfBlast()* getPowderType().rangeModifier; if (distanceToEntity < radius) { float dam = getDamage(); if(getCasing() != 2 && distanceToEntity > radius/2) { double sc = distanceToEntity-(radius/2); if(sc < 0)sc = 0; if(sc > (radius/2))sc = (radius/2); dam *= (sc / (radius/2)); } if(!(entityHit instanceof EntityItem)) { DamageSource source = mineDmg; if(getFilling() == 2) { source = mineFireDmg; } if(entityHit.attackEntityFrom(source, dam)) { applyEffects(entityHit); } } } } } this.setDead(); } int t = getFilling(); if(t > 0) { for(int a = 0; a < 16; a++) { float range = 0.6F; EntityShrapnel shrapnel = new EntityShrapnel(worldObj, posX, posY+0.5D, posZ, (rand.nextDouble()-0.5)*(range/2), (rand.nextDouble())*range, (rand.nextDouble()-0.5)*(range/2)); if(t == 2) { shrapnel.setFire(10); } worldObj.spawnEntityInWorld(shrapnel); } } } private void applyEffects(Entity hit) { if(getFilling() == 2) { hit.setFire(8); } if(hit instanceof EntityLivingBase) { EntityLivingBase live = (EntityLivingBase)hit; } } private double getRangeOfBlast() { return getBlast().range * getCase().rangeModifier; } private float getDamage() { return getBlast().damage * getCase().damageModifier * getPowderType().damageModifier; } private static DamageSource mineDmg = new DamageSource("mine").setExplosion(); private static DamageSource mineFireDmg = new DamageSource("mine").setExplosion().setFireDamage(); public boolean canEntityBeSeen(Entity entity) { return this.worldObj.rayTraceBlocks(Vec3.createVectorHelper(this.posX, this.posY + this.getEyeHeight(), this.posZ), Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ)) == null; } private final int typeId = 2; public byte getFilling() { return dataWatcher.getWatchableObjectByte(typeId); } public byte getCasing() { return dataWatcher.getWatchableObjectByte(typeId+1); } public byte getFuse() { return dataWatcher.getWatchableObjectByte(typeId+2); } public byte getPowder() { return dataWatcher.getWatchableObjectByte(typeId+3); } public EntityMine setType(byte fill, byte casing, byte fuse, byte powder) { dataWatcher.updateObject(typeId, fill); dataWatcher.updateObject(typeId+1, casing); dataWatcher.updateObject(typeId+2, fuse); dataWatcher.updateObject(typeId+3, powder); this.fuse = getFuseType().time; return this; } private EnumExplosiveType getBlast() { return EnumExplosiveType.getType(getFilling()); } private EnumCasingType getCase() { return EnumCasingType.getType(getCasing()); } private EnumFuseType getFuseType() { return EnumFuseType.getType(getFuse()); } private EnumPowderType getPowderType() { return EnumPowderType.getType(getPowder()); } }