194 lines
6.5 KiB
Java

package com.hbm.entity.projectile;
import java.util.List;
import com.hbm.items.weapon.sedna.BulletConfig;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class EntityBulletBeamBase extends Entity implements IEntityAdditionalSpawnData {
public EntityLivingBase thrower;
public BulletConfig config;
public float damage;
public double headingX;
public double headingY;
public double headingZ;
public double beamLength;
public EntityBulletBeamBase(World world) {
super(world);
this.ignoreFrustumCheck = true;
this.renderDistanceWeight = 10.0D;
this.setSize(0.5F, 0.5F);
}
public EntityBulletBeamBase(EntityLivingBase entity, BulletConfig config, float baseDamage, float angularInaccuracy, double sideOffset, double heightOffset, double frontOffset) {
this(entity.worldObj);
this.thrower = entity;
this.setBulletConfig(config);
this.damage = baseDamage * this.config.damageMult;
this.setLocationAndAngles(thrower.posX, thrower.posY + thrower.getEyeHeight(), thrower.posZ, thrower.rotationYaw + (float) rand.nextGaussian() * angularInaccuracy, thrower.rotationPitch + (float) rand.nextGaussian() * angularInaccuracy);
Vec3 offset = Vec3.createVectorHelper(sideOffset, heightOffset, frontOffset);
offset.rotateAroundX(-this.rotationPitch / 180F * (float) Math.PI);
offset.rotateAroundY(-this.rotationYaw / 180F * (float) Math.PI);
this.posX += offset.xCoord;
this.posY += offset.yCoord;
this.posZ += offset.zCoord;
this.setPosition(this.posX, this.posY, this.posZ);
this.headingX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI));
this.headingZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI));
this.headingY = (double) (-MathHelper.sin((this.rotationPitch) / 180.0F * (float) Math.PI));
double range = 150D;
this.headingX *= range;
this.headingY *= range;
this.headingZ *= range;
performHitscan();
}
@Override
protected void entityInit() {
this.dataWatcher.addObject(3, Integer.valueOf(0));
}
public void setBulletConfig(BulletConfig config) {
this.config = config;
this.dataWatcher.updateObject(3, config.id);
}
public BulletConfig getBulletConfig() {
int id = this.dataWatcher.getWatchableObjectInt(3);
if(id < 0 || id > BulletConfig.configs.size()) return null;
return BulletConfig.configs.get(id);
}
@Override
public void onUpdate() {
if(config == null) config = this.getBulletConfig();
if(config == null){
this.setDead();
return;
}
super.onUpdate();
if(!worldObj.isRemote && this.ticksExisted > config.expires) this.setDead();
}
protected void performHitscan() {
Vec3 pos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
Vec3 nextPos = Vec3.createVectorHelper(this.posX + this.headingX, this.posY + this.headingY, this.posZ + this.headingZ);
MovingObjectPosition mop = null;
if(!this.isSpectral()) mop = this.worldObj.func_147447_a(pos, nextPos, false, true, false);
pos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
nextPos = Vec3.createVectorHelper(this.posX + this.headingX, this.posY + this.headingY, this.posZ + this.headingZ);
if(mop != null) {
nextPos = Vec3.createVectorHelper(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
}
if(!this.worldObj.isRemote && this.doesImpactEntities()) {
Entity hitEntity = null;
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.headingX, this.headingY, this.headingZ).expand(1.0D, 1.0D, 1.0D));
double nearest = 0.0D;
MovingObjectPosition nonPenImpact = null;
for(int j = 0; j < list.size(); ++j) {
Entity entity = (Entity) list.get(j);
if(entity.canBeCollidedWith() && entity != thrower) {
double hitbox = 0.3F;
AxisAlignedBB aabb = entity.boundingBox.expand(hitbox, hitbox, hitbox);
MovingObjectPosition hitMop = aabb.calculateIntercept(pos, nextPos);
if(hitMop != null) {
// if penetration is enabled, run impact for all intersecting entities
if(this.doesPenetrate()) {
this.onImpact(new MovingObjectPosition(entity, hitMop.hitVec));
} else {
double dist = pos.distanceTo(hitMop.hitVec);
if(dist < nearest || nearest == 0.0D) {
hitEntity = entity;
nearest = dist;
nonPenImpact = hitMop;
}
}
}
}
}
// if not, only run it for the closest MOP
if(!this.doesPenetrate() && hitEntity != null) {
mop = new MovingObjectPosition(hitEntity, nonPenImpact.hitVec);
}
}
if(mop != null) {
if(mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK && this.worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ) == Blocks.portal) {
this.setInPortal();
} else {
this.onImpact(mop);
}
Vec3 vec = Vec3.createVectorHelper(mop.hitVec.xCoord - posX, mop.hitVec.yCoord - posY, mop.hitVec.zCoord - posZ);
this.beamLength = vec.lengthVector();
} else {
Vec3 vec = Vec3.createVectorHelper(nextPos.xCoord - posX, nextPos.yCoord - posY, nextPos.zCoord - posZ);
this.beamLength = vec.lengthVector();
}
}
protected void onImpact(MovingObjectPosition mop) {
if(!worldObj.isRemote) {
if(this.config.onImpactBeam != null) this.config.onImpactBeam.accept(this, mop);
}
}
public boolean doesImpactEntities() { return this.config.impactsEntities; }
public boolean doesPenetrate() { return this.config.doesPenetrate; }
public boolean isSpectral() { return this.config.isSpectral; }
@Override @SideOnly(Side.CLIENT) public float getShadowSize() { return 0.0F; }
@Override protected void writeEntityToNBT(NBTTagCompound nbt) { }
@Override public boolean writeToNBTOptional(NBTTagCompound nbt) { return false; }
@Override public void readEntityFromNBT(NBTTagCompound nbt) { this.setDead(); }
@Override public void writeSpawnData(ByteBuf buf) {
buf.writeDouble(beamLength);
}
@Override public void readSpawnData(ByteBuf buf) {
this.beamLength = buf.readDouble();
}
}