Bob ba12143cc8 🅱️alls
2025-01-05 22:37:16 +01:00

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; }
}