mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
205 lines
6.9 KiB
Java
205 lines
6.9 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);
|
|
this.isImmuneToFire = true;
|
|
}
|
|
|
|
public EntityLivingBase getThrower() { return this.thrower; }
|
|
|
|
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 = 250D;
|
|
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;
|
|
}
|
|
|
|
if(config.onUpdate != null) config.onUpdate.accept(this);
|
|
|
|
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);
|
|
buf.writeFloat(rotationYaw);
|
|
buf.writeFloat(rotationPitch);
|
|
}
|
|
@Override public void readSpawnData(ByteBuf buf) {
|
|
this.beamLength = buf.readDouble();
|
|
this.rotationYaw = buf.readFloat();
|
|
this.rotationPitch = buf.readFloat();
|
|
}
|
|
|
|
@Override @SideOnly(Side.CLIENT) public boolean canRenderOnFire() { return false; }
|
|
}
|