mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
206 lines
7.8 KiB
Java
206 lines
7.8 KiB
Java
package com.hbm.entity.projectile;
|
|
|
|
import com.hbm.items.weapon.sedna.BulletConfig;
|
|
import com.hbm.util.BobMathUtil;
|
|
import com.hbm.util.TrackerUtil;
|
|
import com.hbm.util.Vec3NT;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.EntityTrackerEntry;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.MovingObjectPosition;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.WorldServer;
|
|
|
|
public class EntityBulletBaseMK4 extends EntityThrowableInterp {
|
|
|
|
public BulletConfig config;
|
|
//used for rendering tracers
|
|
public double velocity;
|
|
public double prevVelocity;
|
|
public double accel;
|
|
public float damage;
|
|
public int ricochets = 0;
|
|
public Entity lockonTarget = null;
|
|
|
|
public EntityBulletBaseMK4(World world) {
|
|
super(world);
|
|
this.renderDistanceWeight = 10.0D;
|
|
this.setSize(0.5F, 0.5F);
|
|
this.isImmuneToFire = true;
|
|
}
|
|
|
|
/** For submunitions! */
|
|
public EntityBulletBaseMK4(World world, EntityLivingBase entity, BulletConfig config, float damage, float gunSpread, double posX, double posY, double posZ, double motionX, double motionY, double motionZ) {
|
|
this(world);
|
|
|
|
this.thrower = entity;
|
|
this.setBulletConfig(config);
|
|
|
|
this.damage = damage;
|
|
|
|
this.setLocationAndAngles(posX, posY, posZ, 0, 0);
|
|
this.setPosition(this.posX, this.posY, this.posZ);
|
|
|
|
this.motionX = motionX;
|
|
this.motionY = motionY;
|
|
this.motionZ = motionZ;
|
|
|
|
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread + gunSpread);
|
|
}
|
|
|
|
/** For standard guns */
|
|
public EntityBulletBaseMK4(EntityLivingBase entity, BulletConfig config, float baseDamage, float gunSpread, 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, thrower.rotationPitch);
|
|
|
|
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.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
|
this.motionZ = MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
|
this.motionY = (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI));
|
|
|
|
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread + gunSpread);
|
|
}
|
|
|
|
/** For turrets - angles are in radians, and pitch is negative! */
|
|
public EntityBulletBaseMK4(World world, BulletConfig config, float baseDamage, float gunSpread, float yaw, float pitch) {
|
|
this(world);
|
|
|
|
this.setBulletConfig(config);
|
|
this.damage = baseDamage * this.config.damageMult;
|
|
|
|
this.prevRotationYaw = this.rotationYaw = yaw * 180F / (float) Math.PI;
|
|
this.prevRotationPitch = this.rotationPitch = -pitch * 180F / (float) Math.PI;
|
|
|
|
this.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
|
this.motionZ = MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI);
|
|
this.motionY = (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI));
|
|
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread + gunSpread);
|
|
}
|
|
|
|
@Override
|
|
protected void entityInit() {
|
|
super.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;
|
|
}
|
|
|
|
this.prevPosX = this.posX;
|
|
this.prevPosY = this.posY;
|
|
this.prevPosZ = this.posZ;
|
|
|
|
super.onUpdate();
|
|
|
|
double dX = this.posX - this.prevPosX;
|
|
double dY = this.posY - this.prevPosY;
|
|
double dZ = this.posZ - this.prevPosZ;
|
|
|
|
if(this.lockonTarget != null && !this.lockonTarget.isDead) {
|
|
Vec3NT motion = new Vec3NT(motionX, motionY, motionZ);
|
|
double vel = motion.lengthVector();
|
|
Vec3NT delta = new Vec3NT(lockonTarget.posX - posX, lockonTarget.posY + lockonTarget.height / 2D - posY, lockonTarget.posZ - posZ);
|
|
float turn = Math.min(0.005F * this.ticksExisted, 1F);
|
|
Vec3NT newVec = new Vec3NT(
|
|
BobMathUtil.interp(motion.xCoord, delta.xCoord, turn),
|
|
BobMathUtil.interp(motion.yCoord, delta.yCoord, turn),
|
|
BobMathUtil.interp(motion.zCoord, delta.zCoord, turn)).normalizeSelf().multiply(vel);
|
|
this.motionX = newVec.xCoord;
|
|
this.motionY = newVec.yCoord;
|
|
this.motionZ = newVec.zCoord;
|
|
EntityTrackerEntry entry = TrackerUtil.getTrackerEntry((WorldServer) worldObj, this.getEntityId());
|
|
entry.lastYaw = MathHelper.floor_float(this.rotationYaw * 256.0F / 360.0F) + 10; //force-trigger rotation update
|
|
}
|
|
|
|
this.prevVelocity = this.velocity;
|
|
this.velocity = Math.sqrt(dX * dX + dY * dY + dZ * dZ);
|
|
|
|
if(!this.onGround && velocity > 0) {
|
|
|
|
float hyp = MathHelper.sqrt_double(dX * dX + dZ * dZ);
|
|
this.rotationYaw = (float) (Math.atan2(dX, dZ) * 180.0D / Math.PI);
|
|
|
|
for(this.rotationPitch = (float) (Math.atan2(dY, (double) hyp) * 180.0D / 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;
|
|
}
|
|
|
|
if(!worldObj.isRemote && this.ticksExisted > config.expires) this.setDead();
|
|
|
|
if(this.config.onUpdate != null) this.config.onUpdate.accept(this);
|
|
}
|
|
|
|
@Override
|
|
public void setDead() {
|
|
super.setDead();
|
|
|
|
//send a teleport on collision so that the bullets are forced to move even if their lifetime is only 1 tick, letting them render
|
|
if(worldObj instanceof WorldServer) TrackerUtil.sendTeleport((WorldServer) worldObj, this);
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void onImpact(MovingObjectPosition mop) {
|
|
if(!worldObj.isRemote) {
|
|
|
|
if(this.config.onImpact != null) this.config.onImpact.accept(this, mop);
|
|
if(this.isDead) return;
|
|
if(this.config.onRicochet != null) this.config.onRicochet.accept(this, mop);
|
|
if(this.config.onEntityHit != null) this.config.onEntityHit.accept(this, mop);
|
|
}
|
|
}
|
|
|
|
@Override protected double headingForceMult() { return 1D; }
|
|
@Override public double getGravityVelocity() { return this.config.gravity; }
|
|
@Override protected double motionMult() { return this.config.velocity + this.accel; }
|
|
@Override protected float getAirDrag() { return 1F; }
|
|
@Override protected float getWaterDrag() { return 1F; }
|
|
|
|
@Override public boolean doesImpactEntities() { return this.config.impactsEntities; }
|
|
@Override public boolean doesPenetrate() { return this.config.doesPenetrate; }
|
|
@Override public boolean isSpectral() { return this.config.isSpectral; }
|
|
@Override public int selfDamageDelay() { return this.config.selfDamageDelay; }
|
|
|
|
@Override @SideOnly(Side.CLIENT) public boolean canRenderOnFire() { return false; }
|
|
}
|