entity:
package guru.tbe.entity;
import com.google.common.base.Optional;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityCreativeOrb extends EntityOrb
{
private static final DataParameter<Optional<ItemStack>> FIREWORK_ITEM = EntityDataManager.<Optional<ItemStack>>createKey(EntityCreativeOrb.class, DataSerializers.OPTIONAL_ITEM_STACK);
private int fireworkAge;
private int lifetime;
public EntityCreativeOrb(World worldIn)
{
super(worldIn);
}
protected void entityInit()
{
this.dataManager.register(FIREWORK_ITEM, Optional.<ItemStack>absent());
}
public EntityCreativeOrb(World worldIn, EntityLivingBase throwerIn)
{
super(worldIn, throwerIn);
}
public EntityCreativeOrb(World worldIn, double x, double y, double z, ItemStack givenItem)
{
super(worldIn);
this.fireworkAge = 0;
int i = 1;
if (givenItem != null && givenItem.hasTagCompound())
{
this.dataManager.set(FIREWORK_ITEM, Optional.of(givenItem));
NBTTagCompound nbttagcompound = givenItem.getTagCompound();
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Fireworks");
i += nbttagcompound1.getByte("Flight");
}
this.lifetime = 10 * i + this.rand.nextInt(6) + this.rand.nextInt(7);
}
public void onUpdate()
{
++this.fireworkAge;
if (!this.worldObj.isRemote && this.fireworkAge > this.lifetime)
{
this.worldObj.setEntityState(this, (byte)17);
this.setDead();
}
}
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 17 && this.worldObj.isRemote)
{
ItemStack itemstack = (ItemStack)((Optional)this.dataManager.get(FIREWORK_ITEM)).orNull();
NBTTagCompound nbttagcompound = null;
if (itemstack != null && itemstack.hasTagCompound())
{
nbttagcompound = itemstack.getTagCompound().getCompoundTag("Fireworks");
}
this.worldObj.makeFireworks(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, nbttagcompound);
}
super.handleStatusUpdate(id);
}
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
tagCompound.setInteger("Life", this.fireworkAge);
tagCompound.setInteger("LifeTime", this.lifetime);
ItemStack itemstack = (ItemStack)((Optional)this.dataManager.get(FIREWORK_ITEM)).orNull();
if (itemstack != null)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
itemstack.writeToNBT(nbttagcompound);
tagCompound.setTag("FireworksItem", nbttagcompound);
}
}
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
this.fireworkAge = tagCompund.getInteger("Life");
this.lifetime = tagCompund.getInteger("LifeTime");
NBTTagCompound nbttagcompound = tagCompund.getCompoundTag("FireworksItem");
if (nbttagcompound != null)
{
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound);
if (itemstack != null)
{
this.dataManager.set(FIREWORK_ITEM, Optional.of(itemstack));
}
}
}
public float getBrightness(float partialTicks)
{
return super.getBrightness(partialTicks);
}
@SideOnly(Side.CLIENT)
public int getBrightnessForRender(float partialTicks)
{
return super.getBrightnessForRender(partialTicks);
}
@Override
protected void onImpact(RayTraceResult result)
{
}
}
item:
package guru.tbe.item;
import guru.tbe.entity.EntityCreativeOrb;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.world.World;
public class ItemCreativeOrb extends Item
{
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
{
if (!playerIn.capabilities.isCreativeMode)
{
--itemStackIn.stackSize;
}
worldIn.playSound((EntityPlayer)null, playerIn.posX, playerIn.posY, playerIn.posZ, SoundEvents.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.4F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
if (!worldIn.isRemote)
{
EntityCreativeOrb entitythrowable = new EntityCreativeOrb(worldIn, playerIn);
entitythrowable.func_184538_a(playerIn, playerIn.rotationPitch, playerIn.rotationYaw, 0.0F, 1.5F, 1.0F);
worldIn.spawnEntityInWorld(entitythrowable);
}
playerIn.addStat(StatList.getObjectUseStats(this));
return new ActionResult(EnumActionResult.SUCCESS, itemStackIn);
}
}
Orb that Creative Orb is extending:
package guru.tbe.entity;
import java.util.List;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
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.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class EntityOrb extends Entity implements IProjectile
{
private int xTile;
private int yTile;
private int zTile;
private Block inTile;
protected boolean inGround;
public int throwableShake;
private EntityLivingBase thrower;
private String throwerName;
private int ticksInGround;
private int ticksInAir;
public Entity field_184539_c;
private int field_184540_av;
public EntityOrb(World worldIn)
{
super(worldIn);
this.xTile = -1;
this.yTile = -1;
this.zTile = -1;
this.setSize(0.41F, 0.41F);
}
public EntityOrb(World worldIn, double x, double y, double z)
{
this(worldIn);
this.setPosition(x, y, z);
}
public EntityOrb(World worldIn, EntityLivingBase throwerIn)
{
this(worldIn, throwerIn.posX, throwerIn.posY + (double)throwerIn.getEyeHeight() - 0.10000000149011612D, throwerIn.posZ);
this.thrower = throwerIn;
}
public boolean canRenderOnFire()
{
return false;
}
protected void entityInit()
{
}
@SideOnly(Side.CLIENT)
public boolean isInRangeToRenderDist(double distance)
{
double d0 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;
if (Double.isNaN(d0))
{
d0 = 4.0D;
}
d0 = d0 * 64.0D;
return distance < d0 * d0;
}
public void func_184538_a(Entity p_184538_1_, float p_184538_2_, float p_184538_3_, float p_184538_4_, float p_184538_5_, float p_184538_6_)
{
float f = -MathHelper.sin(p_184538_3_ * 0.017453292F) * MathHelper.cos(p_184538_2_ * 0.017453292F);
float f1 = -MathHelper.sin((p_184538_2_ + p_184538_4_) * 0.017453292F);
float f2 = MathHelper.cos(p_184538_3_ * 0.017453292F) * MathHelper.cos(p_184538_2_ * 0.017453292F);
this.setThrowableHeading((double)f, (double)f1, (double)f2, p_184538_5_, p_184538_6_);
this.motionX += p_184538_1_.motionX;
this.motionZ += p_184538_1_.motionZ;
if (!p_184538_1_.onGround)
{
this.motionY += p_184538_1_.motionY;
}
}
public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy)
{
float f = MathHelper.sqrt_double(x * x + y * y + z * z);
x = x / (double)f;
y = y / (double)f;
z = z / (double)f;
x = x + this.rand.nextGaussian() * 0.0D * (double)inaccuracy;
y = y + this.rand.nextGaussian() * 0.0D * (double)inaccuracy;
z = z + this.rand.nextGaussian() * 0.0D * (double)inaccuracy;
x = x * (double)velocity;
y = y * (double)velocity;
z = z * (double)velocity;
this.motionX = x;
this.motionY = y;
this.motionZ = z;
float f1 = MathHelper.sqrt_double(x * x + z * z);
this.prevRotationYaw = this.rotationYaw = (float)(MathHelper.atan2(x, z) * (180D / Math.PI));
this.prevRotationPitch = this.rotationPitch = (float)(MathHelper.atan2(y, (double)f1) * (180D / Math.PI));
this.ticksInGround = 0;
}
@SideOnly(Side.CLIENT)
public void setVelocity(double x, double y, double z)
{
this.motionX = x;
this.motionY = y;
this.motionZ = z;
if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F)
{
float f = MathHelper.sqrt_double(x * x + z * z);
this.prevRotationYaw = this.rotationYaw = (float)(MathHelper.atan2(x, z) * (180D / Math.PI));
this.prevRotationPitch = this.rotationPitch = (float)(MathHelper.atan2(y, (double)f) * (180D / Math.PI));
}
}
public void onUpdate()
{
this.lastTickPosX = this.posX;
this.lastTickPosY = this.posY;
this.lastTickPosZ = this.posZ;
super.onUpdate();
if (this.throwableShake > 0)
{
--this.throwableShake;
}
if (this.inGround)
{
if (this.worldObj.getBlockState(new BlockPos(this.xTile, this.yTile, this.zTile)).getBlock() == this.inTile)
{
++this.ticksInGround;
if (this.ticksInGround == 1200)
{
this.setDead();
}
return;
}
this.inGround = false;
this.motionX *= (double)(this.rand.nextFloat() * 0.2F);
this.motionY *= (double)(this.rand.nextFloat() * 0.2F);
this.motionZ *= (double)(this.rand.nextFloat() * 0.2F);
this.ticksInGround = 0;
this.ticksInAir = 0;
}
else
{
++this.ticksInAir;
}
Vec3d vec3d = new Vec3d(this.posX, this.posY, this.posZ);
Vec3d vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
RayTraceResult raytraceresult = this.worldObj.rayTraceBlocks(vec3d, vec3d1);
vec3d = new Vec3d(this.posX, this.posY, this.posZ);
vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
if (raytraceresult != null)
{
vec3d1 = new Vec3d(raytraceresult.hitVec.xCoord, raytraceresult.hitVec.yCoord, raytraceresult.hitVec.zCoord);
}
Entity entity = null;
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expandXyz(1.0D));
double d0 = 0.0D;
boolean flag = false;
for (int i = 0; i < list.size(); ++i)
{
Entity entity1 = (Entity)list.get(i);
if (entity1.canBeCollidedWith())
{
if (entity1 == this.field_184539_c)
{
flag = true;
}
else if (this.ticksExisted < 2 && this.field_184539_c == null)
{
this.field_184539_c = entity1;
flag = true;
}
else
{
flag = false;
AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().expandXyz(0.30000001192092896D);
RayTraceResult raytraceresult1 = axisalignedbb.calculateIntercept(vec3d, vec3d1);
if (raytraceresult1 != null)
{
double d1 = vec3d.squareDistanceTo(raytraceresult1.hitVec);
if (d1 < d0 || d0 == 0.0D)
{
entity = entity1;
d0 = d1;
}
}
}
}
}
if (this.field_184539_c != null)
{
if (flag)
{
this.field_184540_av = 2;
}
else if (this.field_184540_av-- <= 0)
{
this.field_184539_c = null;
}
}
if (entity != null)
{
raytraceresult = new RayTraceResult(entity);
}
if (raytraceresult != null)
{
if (raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK && this.worldObj.getBlockState(raytraceresult.getBlockPos()).getBlock() == Blocks.PORTAL)
{
this.setPortal(raytraceresult.getBlockPos());
}
else
{
this.onImpact(raytraceresult);
}
}
this.posX += this.motionX;
this.posY += this.motionY;
this.posZ += this.motionZ;
float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
this.rotationYaw = (float)(MathHelper.atan2(this.motionX, this.motionZ) * (180D / Math.PI));
for (this.rotationPitch = (float)(MathHelper.atan2(this.motionY, (double)f) * (180D / Math.PI)); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F)
while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
{
this.prevRotationPitch += 360.0F;
}
while (this.rotationYaw - this.prevRotationYaw < -180.0F)
{
this.prevRotationYaw -= 360.0F;
}
while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
{
this.prevRotationYaw += 360.0F;
}
this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
float f1 = 0.99F;
float f2 = this.getGravityVelocity();
if (this.isInWater())
{
for (int j = 0; j < 4; ++j)
{
float f3 = 0.0F;
this.worldObj.spawnParticle(EnumParticleTypes.WATER_BUBBLE, posX + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) / 2, posY + (worldObj.rand.nextFloat() / -2 - worldObj.rand.nextFloat()) / -1, posZ + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) / 2, 0, 0, 0);
}
f1 = 0.8F;
}
this.motionX *= (double)f1;
this.motionY *= (double)f1;
this.motionZ *= (double)f1;
this.motionY -= (double)f2;
this.setPosition(this.posX, this.posY, this.posZ);
}
protected float getGravityVelocity()
{
return 0.03F;
}
protected abstract void onImpact(RayTraceResult result);
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
tagCompound.setInteger("xTile", this.xTile);
tagCompound.setInteger("yTile", this.yTile);
tagCompound.setInteger("zTile", this.zTile);
ResourceLocation resourcelocation = (ResourceLocation)Block.REGISTRY.getNameForObject(this.inTile);
tagCompound.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString());
tagCompound.setByte("shake", (byte)this.throwableShake);
tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
if ((this.throwerName == null || this.throwerName.isEmpty()) && this.thrower instanceof EntityPlayer)
{
this.throwerName = this.thrower.getName();
}
tagCompound.setString("ownerName", this.throwerName == null ? "" : this.throwerName);
}
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
this.xTile = tagCompund.getInteger("xTile");
this.yTile = tagCompund.getInteger("yTile");
this.zTile = tagCompund.getInteger("zTile");
if (tagCompund.hasKey("inTile", )
{
this.inTile = Block.getBlockFromName(tagCompund.getString("inTile"));
}
else
{
this.inTile = Block.getBlockById(tagCompund.getByte("inTile") & 255);
}
this.throwableShake = tagCompund.getByte("shake") & 255;
this.inGround = tagCompund.getByte("inGround") == 1;
this.thrower = null;
this.throwerName = tagCompund.getString("ownerName");
if (this.throwerName != null && this.throwerName.isEmpty())
{
this.throwerName = null;
}
this.thrower = this.getThrower();
}
public EntityLivingBase getThrower()
{
if (this.thrower == null && this.throwerName != null && !this.throwerName.isEmpty())
{
this.thrower = this.worldObj.getPlayerEntityByName(this.throwerName);
if (this.thrower == null && this.worldObj instanceof WorldServer)
{
try
{
Entity entity = ((WorldServer)this.worldObj).getEntityFromUuid(UUID.fromString(this.throwerName));
if (entity instanceof EntityLivingBase)
{
this.thrower = (EntityLivingBase)entity;
}
}
catch (Throwable var2)
{
this.thrower = null;
}
}
}
return this.thrower;
}
}
This will assure that your firework will be 100% accurate where you aim it is where its going, and all that good stuff. It throws, but it doesn't actually throw. Like it doesn't fling out forward from the player or anything.
You right click, it exists, then its gone. Real simple process. (like a giant sparkler) When summoned with the nbts n stuff It explodes and acts normal.