mirror of
https://github.com/GTNewHorizons/Electro-Magic-Tools.git
synced 2026-11-13 17:04:02 +00:00
269 lines
8.0 KiB
Java
269 lines
8.0 KiB
Java
package emt.entity;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import emt.util.EMTRandomHelper.Bolt;
|
|
import emt.util.EMTRandomHelper.Point;
|
|
import io.netty.buffer.ByteBuf;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.IProjectile;
|
|
import net.minecraft.entity.projectile.EntityFireball;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTTagList;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.MovingObjectPosition;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.chunk.Chunk;
|
|
|
|
public class EntityEnergyBall extends Entity implements IProjectile, IEntityAdditionalSpawnData {
|
|
public static final int RADIUS = 8;
|
|
public static final float LENGTH = 16f;
|
|
public static final float DIST = 1f;
|
|
public static final float HEIGHT = 8f;
|
|
public static final int MAX_TICKS_IN_TILE = 60;
|
|
public static final int MAX_COUNT_OF_BOLTS = 25;
|
|
|
|
public EntityLivingBase shootingEntity;
|
|
public Bolt[] bolts = new Bolt[MAX_COUNT_OF_BOLTS];
|
|
public Point[] entityPositions;
|
|
public Bolt[][] entityBolts;
|
|
|
|
public boolean inTile = false;
|
|
public int ticksAlive = 1; /** Pls, don't ask me why 1 =) **/
|
|
public int ticksInAir = 1;
|
|
public double accelerationX = 0;
|
|
public double accelerationY = 0;
|
|
public double accelerationZ = 0;
|
|
|
|
public EntityEnergyBall(World world, EntityLivingBase shootingEntity, double rotX, double rotY, double rotZ) {
|
|
this(world, shootingEntity);
|
|
|
|
rotX += this.rand.nextGaussian() * 0.4D;
|
|
rotY += this.rand.nextGaussian() * 0.4D;
|
|
rotZ += this.rand.nextGaussian() * 0.4D;
|
|
double len = (double) MathHelper.sqrt_double((rotX * rotX) + (rotY * rotY) + (rotZ * rotZ));
|
|
this.accelerationX = rotX / len * 0.1D;
|
|
this.accelerationY = rotY / len * 0.1D;
|
|
this.accelerationZ = rotZ / len * 0.1D;
|
|
}
|
|
|
|
public EntityEnergyBall(World world, EntityLivingBase shootingEntity) {
|
|
this(world);
|
|
|
|
this.shootingEntity = shootingEntity;
|
|
this.setLocationAndAngles(shootingEntity.posX, shootingEntity.posY + shootingEntity.getEyeHeight(), shootingEntity.posZ, shootingEntity.rotationYaw, shootingEntity.rotationPitch);
|
|
}
|
|
|
|
public EntityEnergyBall(World world) {
|
|
super(world);
|
|
|
|
this.setSize(1.0F, 1.0F);
|
|
this.ignoreFrustumCheck = true;
|
|
this.setPosition(this.posX, this.posY, this.posZ);
|
|
this.yOffset = 0.0F;
|
|
this.motionX = this.motionY = this.motionZ = 0.0D;
|
|
|
|
for (int i = 0; i < bolts.length; i++) {
|
|
bolts[i] = new Bolt(DIST, LENGTH, HEIGHT);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void writeSpawnData(ByteBuf buffer) {
|
|
buffer.writeDouble(accelerationX);
|
|
buffer.writeDouble(accelerationY);
|
|
buffer.writeDouble(accelerationZ);
|
|
}
|
|
|
|
@Override
|
|
public void readSpawnData(ByteBuf buffer) {
|
|
accelerationX = buffer.readDouble();
|
|
accelerationY = buffer.readDouble();
|
|
accelerationZ = buffer.readDouble();
|
|
}
|
|
|
|
@Override
|
|
public void onUpdate() {
|
|
super.onUpdate();
|
|
|
|
/** If in Tile **/
|
|
if (this.inTile) {
|
|
this.ticksAlive++;
|
|
|
|
if (this.ticksAlive >= MAX_TICKS_IN_TILE) {
|
|
this.setDead();
|
|
}
|
|
|
|
/** Generating Coords for every Entity **/
|
|
ArrayList<Entity> entities = new ArrayList();
|
|
|
|
int chunkSize = ((RADIUS - 1) >> 4) + 2;
|
|
|
|
for (int chX = -chunkSize; chX < chunkSize; chX++) {
|
|
for (int chZ = -chunkSize; chZ < chunkSize; chZ++) {
|
|
Chunk chunk = worldObj.getChunkFromChunkCoords(chX + (int) (this.posX / 16), chZ + (int) (this.posZ / 16));
|
|
|
|
if (chunk.isChunkLoaded && chunk.hasEntities) {
|
|
for (int i = 0; i < chunk.entityLists.length; i++) {
|
|
for (int k = 0; k < chunk.entityLists[i].size(); k++) {
|
|
Entity entity = (Entity) chunk.entityLists[i].get(k);
|
|
double width = entity.posX - this.posX;
|
|
double height = entity.posY - this.posY;
|
|
double length = entity.posZ - this.posZ;
|
|
double hyp = MathHelper.sqrt_double((width * width) + (length * length) + (height * height));
|
|
|
|
if (hyp <= RADIUS) {
|
|
entities.add(entity);
|
|
/** Closer - Harder */
|
|
entity.attackEntityFrom(DamageSource.magic, (float) (RADIUS - hyp));
|
|
entity.performHurtAnimation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(worldObj.isRemote) {
|
|
entityBolts = new Bolt[entities.size()][MAX_COUNT_OF_BOLTS];
|
|
}
|
|
|
|
entityPositions = new Point[entities.size()];
|
|
|
|
for (int i = 0; i < entities.size(); i++) {
|
|
Entity entity = entities.get(i);
|
|
entityPositions[i] = new Point(entity.posX, entity.posY, entity.posZ);
|
|
if (this.worldObj.isRemote) {
|
|
|
|
for (int e = 0; e < bolts.length; e++) {
|
|
float h = entity.height;
|
|
if(h < 4) {
|
|
h = 4;
|
|
}
|
|
entityBolts[i][e] = new Bolt(h / 10, h, h / 2);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
}
|
|
/** If not in Tile **/
|
|
else {
|
|
/** Collision detection **/
|
|
Vec3 vec3 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
|
|
Vec3 vec3next = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
|
MovingObjectPosition mop = this.worldObj.rayTraceBlocks(vec3, vec3next);
|
|
|
|
this.ticksInAir++;
|
|
if (mop != null) {
|
|
inTile = true;
|
|
}
|
|
|
|
/** Updating position */
|
|
this.posX += this.motionX;
|
|
this.posY += this.motionY;
|
|
this.posZ += this.motionZ;
|
|
float f1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
|
this.rotationYaw = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) + 90.0F;
|
|
|
|
for (this.rotationPitch = (float) (Math.atan2((double) f1, this.motionY) * 180.0D / Math.PI) - 90.0F; 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;
|
|
|
|
double factor = this.getMotionFactor();
|
|
this.motionX += this.accelerationX;
|
|
this.motionY += this.accelerationY;
|
|
this.motionZ += this.accelerationZ;
|
|
this.motionX *= factor;
|
|
this.motionY *= factor;
|
|
this.motionZ *= factor;
|
|
this.setPosition(this.posX, this.posY, this.posZ);
|
|
/************************************************************************/
|
|
}
|
|
|
|
if (this.worldObj.isRemote) {
|
|
for (int i = 0; i < bolts.length; i++) {
|
|
bolts[i].regenerate();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected float getMotionFactor() {
|
|
return 0.85F;
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeCollidedWith() {
|
|
return true;
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public int getBrightnessForRender(float p_70070_1_) {
|
|
return 240;
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
@Override
|
|
public boolean isInRangeToRender3d(double x, double y, double z) {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void entityInit() {
|
|
}
|
|
|
|
@Override
|
|
public void writeEntityToNBT(NBTTagCompound nbt) {
|
|
nbt.setByte("inTile", (byte) (this.inTile ? 1 : 0));
|
|
nbt.setTag("direction", this.newDoubleNBTList(new double[] { this.motionX, this.motionY, this.motionZ }));
|
|
}
|
|
|
|
@Override
|
|
public void readEntityFromNBT(NBTTagCompound nbt) {
|
|
if (!inTile) {
|
|
this.inTile = nbt.getByte("inTile") == 1;
|
|
}
|
|
|
|
if (nbt.hasKey("direction", 9)) {
|
|
NBTTagList nbttaglist = nbt.getTagList("direction", 6);
|
|
this.motionX = nbttaglist.func_150309_d(0);
|
|
this.motionY = nbttaglist.func_150309_d(1);
|
|
this.motionZ = nbttaglist.func_150309_d(2);
|
|
}
|
|
else {
|
|
this.setDead();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void setThrowableHeading(double x, double y, double z, float p1, float p2) {
|
|
}
|
|
}
|