mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
new bullet base code
This commit is contained in:
parent
078566064c
commit
5bcffadbab
@ -17,3 +17,4 @@
|
||||
## Fixed
|
||||
* Fixed issue where mk5 explosions would behave weirdly in their origin chunk, often blowing through bedrock and thick layers of concrete
|
||||
* Fixed saturnite rifle disappearing in third person when scoping
|
||||
* Fixed cables not visually connecting to assemblers
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.hbm.blocks.machine;
|
||||
|
||||
import com.hbm.blocks.BlockDummyable;
|
||||
import com.hbm.tileentity.TileEntityProxyCombo;
|
||||
import com.hbm.tileentity.machine.TileEntityMachineAssembler;
|
||||
|
||||
import net.minecraft.block.material.Material;
|
||||
@ -18,6 +19,7 @@ public class MachineAssembler extends BlockDummyable {
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
if(meta >= 12) return new TileEntityMachineAssembler();
|
||||
if(meta >= 6) return new TileEntityProxyCombo().power();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -158,6 +158,7 @@ public class EntityMappings {
|
||||
addEntity(EntityGrenadeIFNull.class, "entity_grenade_ironshod_null", 250);
|
||||
addEntity(EntityFallingNuke.class, "entity_falling_bomb", 1000);
|
||||
addEntity(EntityBulletBase.class, "entity_bullet_mk2", 250);
|
||||
addEntity(EntityBulletBaseNT.class, "entity_bullet_mk3", 250, false);
|
||||
addEntity(EntityMinerRocket.class, "entity_miner_lander", 1000);
|
||||
addEntity(EntityFogFX.class, "entity_nuclear_fog", 1000);
|
||||
addEntity(EntityDuchessGambit.class, "entity_duchessgambit", 1000);
|
||||
|
||||
@ -47,7 +47,15 @@ import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityBulletBase extends Entity implements IProjectile {
|
||||
public class EntityBulletBase extends Entity implements IProjectile, IBulletBase {
|
||||
|
||||
@Override public double prevX() { return prevRenderX; }
|
||||
@Override public double prevY() { return prevRenderY; }
|
||||
@Override public double prevZ() { return prevRenderZ; }
|
||||
@Override public void prevX(double d) { prevRenderX = d; }
|
||||
@Override public void prevY(double d) { prevRenderY = d; }
|
||||
@Override public void prevZ(double d) { prevRenderZ = d; }
|
||||
@Override public List<Pair<Vec3, Double>> nodes() { return this.trailNodes; }
|
||||
|
||||
private BulletConfiguration config;
|
||||
public EntityLivingBase shooter;
|
||||
|
||||
@ -1,30 +1,63 @@
|
||||
package com.hbm.entity.projectile;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.blocks.generic.RedBarrel;
|
||||
import com.hbm.entity.effect.EntityCloudFleijaRainbow;
|
||||
import com.hbm.entity.effect.EntityEMPBlast;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK3;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.explosion.ExplosionChaos;
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNukeGeneric;
|
||||
import com.hbm.handler.BulletConfigSyncingUtil;
|
||||
import com.hbm.handler.BulletConfiguration;
|
||||
import com.hbm.handler.GunConfiguration;
|
||||
import com.hbm.interfaces.IBulletHitBehavior;
|
||||
import com.hbm.interfaces.IBulletHurtBehavior;
|
||||
import com.hbm.interfaces.IBulletImpactBehavior;
|
||||
import com.hbm.interfaces.IBulletRicochetBehavior;
|
||||
import com.hbm.interfaces.IBulletUpdateBehavior;
|
||||
import com.hbm.items.weapon.ItemGunBase;
|
||||
import com.hbm.main.MainRegistry;
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.potion.HbmPotion;
|
||||
import com.hbm.util.ArmorUtil;
|
||||
import com.hbm.util.BobMathUtil;
|
||||
import com.hbm.util.Tuple.Pair;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
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;
|
||||
|
||||
public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
/**
|
||||
* MK2 which features several improvements:
|
||||
* - uses generic throwable code, reducing boilerplate nonsense
|
||||
* - uses approach-based interpolation, preventing desyncs and making movement silky-smooth
|
||||
* - new adjustments in the base class allow for multiple MOP impacts per frame
|
||||
* - also comes with tons of legacy code to ensure compat (sadly)
|
||||
* @author hbm
|
||||
*/
|
||||
public class EntityBulletBaseNT extends EntityThrowableInterp implements IBulletBase {
|
||||
|
||||
@Override public double prevX() { return prevRenderX; }
|
||||
@Override public double prevY() { return prevRenderY; }
|
||||
@Override public double prevZ() { return prevRenderZ; }
|
||||
@Override public void prevX(double d) { prevRenderX = d; }
|
||||
@Override public void prevY(double d) { prevRenderY = d; }
|
||||
@Override public void prevZ(double d) { prevRenderZ = d; }
|
||||
@Override public List<Pair<Vec3, Double>> nodes() { return this.trailNodes; }
|
||||
|
||||
private BulletConfiguration config;
|
||||
public float overrideDamage;
|
||||
@ -48,6 +81,8 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
super(world);
|
||||
this.config = BulletConfigSyncingUtil.pullConfig(config);
|
||||
this.dataWatcher.updateObject(18, config);
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
this.renderDistanceWeight = 10.0D;
|
||||
|
||||
if(this.config == null) {
|
||||
@ -55,9 +90,6 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
|
||||
this.setSize(0.5F, 0.5F);
|
||||
}
|
||||
|
||||
@ -65,6 +97,8 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
super(world);
|
||||
this.config = BulletConfigSyncingUtil.pullConfig(config);
|
||||
this.dataWatcher.updateObject(18, config);
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
thrower = entity;
|
||||
|
||||
ItemStack gun = entity.getHeldItem();
|
||||
@ -98,10 +132,8 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
this.renderDistanceWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
|
||||
System.out.println("" + this.config.spread);
|
||||
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread * (offsetShot ? 1F : 0.25F));
|
||||
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
}
|
||||
|
||||
public EntityBulletBaseNT(World world, int config, EntityLivingBase entity, EntityLivingBase target, float motion, float deviation) {
|
||||
@ -109,6 +141,8 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
|
||||
this.config = BulletConfigSyncingUtil.pullConfig(config);
|
||||
this.dataWatcher.updateObject(18, config);
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
this.thrower = entity;
|
||||
|
||||
this.renderDistanceWeight = 10.0D;
|
||||
@ -129,9 +163,16 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
this.yOffset = 0.0F;
|
||||
this.setThrowableHeading(d0, d1, d2, motion, deviation);
|
||||
}
|
||||
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
//style
|
||||
this.dataWatcher.addObject(16, Byte.valueOf((byte) 0));
|
||||
//trail
|
||||
this.dataWatcher.addObject(17, Byte.valueOf((byte) 0));
|
||||
//bullet config sync
|
||||
this.dataWatcher.addObject(18, Integer.valueOf((int) 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -176,7 +217,13 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
}
|
||||
|
||||
if(this.config.bUpdate != null) this.config.bntUpdate.behaveUpdate(this);
|
||||
|
||||
if(this.ticksExisted > config.maxAge) this.setDead();
|
||||
}
|
||||
|
||||
this.prevPosX = posX;
|
||||
this.prevPosY = posY;
|
||||
this.prevPosZ = posZ;
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
@ -204,6 +251,261 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
|
||||
if(mop.typeOfHit == mop.typeOfHit.BLOCK) {
|
||||
|
||||
boolean hRic = rand.nextInt(100) < config.HBRC;
|
||||
boolean doesRic = config.doesRicochet || hRic;
|
||||
|
||||
if(!config.isSpectral && !doesRic) {
|
||||
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
|
||||
this.onBlockImpact(mop.blockX, mop.blockY, mop.blockZ);
|
||||
}
|
||||
|
||||
if(doesRic) {
|
||||
|
||||
Vec3 face = null;
|
||||
|
||||
switch(mop.sideHit) {
|
||||
case 0: face = Vec3.createVectorHelper(0, -1, 0); break;
|
||||
case 1: face = Vec3.createVectorHelper(0, 1, 0); break;
|
||||
case 2: face = Vec3.createVectorHelper(0, 0, 1); break;
|
||||
case 3: face = Vec3.createVectorHelper(0, 0, -1); break;
|
||||
case 4: face = Vec3.createVectorHelper(-1, 0, 0); break;
|
||||
case 5: face = Vec3.createVectorHelper(1, 0, 0); break;
|
||||
}
|
||||
|
||||
if(face != null) {
|
||||
|
||||
Vec3 vel = Vec3.createVectorHelper(motionX, motionY, motionZ);
|
||||
vel.normalize();
|
||||
|
||||
boolean lRic = rand.nextInt(100) < config.LBRC;
|
||||
double angle = Math.abs(BobMathUtil.getCrossAngle(vel, face) - 90);
|
||||
|
||||
if(hRic || (angle <= config.ricochetAngle && lRic)) {
|
||||
switch(mop.sideHit) {
|
||||
case 0:
|
||||
case 1: motionY *= -1; break;
|
||||
case 2:
|
||||
case 3: motionZ *= -1; break;
|
||||
case 4:
|
||||
case 5: motionX *= -1; break;
|
||||
}
|
||||
|
||||
if(config.plink == 1)
|
||||
worldObj.playSoundAtEntity(this, "hbm:weapon.ricochet", 0.25F, 1.0F);
|
||||
if(config.plink == 2)
|
||||
worldObj.playSoundAtEntity(this, "hbm:weapon.gBounce", 1.0F, 1.0F);
|
||||
|
||||
onRicochet(mop.blockX, mop.blockY, mop.blockZ);
|
||||
|
||||
} else {
|
||||
if(!worldObj.isRemote) {
|
||||
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
|
||||
onBlockImpact(mop.blockX, mop.blockY, mop.blockZ);
|
||||
}
|
||||
}
|
||||
|
||||
this.posX += (mop.hitVec.xCoord - this.posX) * 0.6;
|
||||
this.posY += (mop.hitVec.yCoord - this.posY) * 0.6;
|
||||
this.posZ += (mop.hitVec.zCoord - this.posZ) * 0.6;
|
||||
|
||||
this.motionX *= config.bounceMod;
|
||||
this.motionY *= config.bounceMod;
|
||||
this.motionZ *= config.bounceMod;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(mop.entityHit != null) {
|
||||
|
||||
DamageSource damagesource = this.config.getDamage(this, this.thrower);
|
||||
Entity victim = mop.entityHit;
|
||||
|
||||
if(!config.doesPenetrate) {
|
||||
this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
|
||||
onEntityImpact(victim);
|
||||
} else {
|
||||
onEntityHurt(victim);
|
||||
}
|
||||
|
||||
float damage = rand.nextFloat() * (config.dmgMax - config.dmgMin) + config.dmgMin;
|
||||
|
||||
if(overrideDamage != 0)
|
||||
damage = overrideDamage;
|
||||
|
||||
boolean headshot = false;
|
||||
|
||||
if(victim instanceof EntityLivingBase && this.config.headshotMult > 1F) {
|
||||
EntityLivingBase living = (EntityLivingBase) victim;
|
||||
double head = living.height - living.getEyeHeight();
|
||||
|
||||
if(!!living.isEntityAlive() && mop.hitVec != null && mop.hitVec.yCoord > (living.posY + living.height - head * 2)) {
|
||||
damage *= this.config.headshotMult;
|
||||
headshot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(victim != null && !victim.attackEntityFrom(damagesource, damage)) {
|
||||
|
||||
try {
|
||||
Field lastDamage = ReflectionHelper.findField(EntityLivingBase.class, "lastDamage", "field_110153_bc");
|
||||
float dmg = (float) damage + lastDamage.getFloat(victim);
|
||||
if(!victim.attackEntityFrom(damagesource, dmg)) headshot = false;
|
||||
} catch (Exception x) { }
|
||||
|
||||
}
|
||||
|
||||
if(!worldObj.isRemote && headshot) {
|
||||
if(victim instanceof EntityLivingBase) {
|
||||
EntityLivingBase living = (EntityLivingBase) victim;
|
||||
double head = living.height - living.getEyeHeight();
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "vanillaburst");
|
||||
data.setInteger("count", 15);
|
||||
data.setDouble("motion", 0.1D);
|
||||
data.setString("mode", "blockdust");
|
||||
data.setInteger("block", Block.getIdFromBlock(Blocks.redstone_block));
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, living.posX, living.posY + living.height - head, living.posZ), new TargetPoint(living.dimension, living.posX, living.posY, living.posZ, 50));
|
||||
worldObj.playSoundEffect(victim.posX, victim.posY, victim.posZ, "mob.zombie.woodbreak", 1.0F, 0.95F + rand.nextFloat() * 0.2F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for when a bullet dies by hitting a block
|
||||
private void onBlockImpact(int bX, int bY, int bZ) {
|
||||
|
||||
if(config.bntImpact != null)
|
||||
config.bntImpact.behaveBlockHit(this, bX, bY, bZ);
|
||||
|
||||
if(!worldObj.isRemote && !config.liveAfterImpact)
|
||||
this.setDead();
|
||||
|
||||
if(config.incendiary > 0 && !this.worldObj.isRemote) {
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX, (int)posY, (int)posZ) == Blocks.air) worldObj.setBlock((int)posX, (int)posY, (int)posZ, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX + 1, (int)posY, (int)posZ) == Blocks.air) worldObj.setBlock((int)posX + 1, (int)posY, (int)posZ, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX - 1, (int)posY, (int)posZ) == Blocks.air) worldObj.setBlock((int)posX - 1, (int)posY, (int)posZ, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX, (int)posY + 1, (int)posZ) == Blocks.air) worldObj.setBlock((int)posX, (int)posY + 1, (int)posZ, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX, (int)posY - 1, (int)posZ) == Blocks.air) worldObj.setBlock((int)posX, (int)posY - 1, (int)posZ, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX, (int)posY, (int)posZ + 1) == Blocks.air) worldObj.setBlock((int)posX, (int)posY, (int)posZ + 1, Blocks.fire);
|
||||
if(worldObj.rand.nextInt(3) == 0 && worldObj.getBlock((int)posX, (int)posY, (int)posZ - 1) == Blocks.air) worldObj.setBlock((int)posX, (int)posY, (int)posZ - 1, Blocks.fire);
|
||||
}
|
||||
|
||||
if(config.emp > 0)
|
||||
ExplosionNukeGeneric.empBlast(this.worldObj, (int)(this.posX + 0.5D), (int)(this.posY + 0.5D), (int)(this.posZ + 0.5D), config.emp);
|
||||
|
||||
if(config.emp > 3) {
|
||||
if (!this.worldObj.isRemote) {
|
||||
|
||||
EntityEMPBlast cloud = new EntityEMPBlast(this.worldObj, config.emp);
|
||||
cloud.posX = this.posX;
|
||||
cloud.posY = this.posY + 0.5F;
|
||||
cloud.posZ = this.posZ;
|
||||
|
||||
this.worldObj.spawnEntityInWorld(cloud);
|
||||
}
|
||||
}
|
||||
|
||||
if(config.jolt > 0 && !worldObj.isRemote)
|
||||
ExplosionLarge.jolt(worldObj, posX, posY, posZ, config.jolt, 150, 0.25);
|
||||
|
||||
if(config.explosive > 0 && !worldObj.isRemote)
|
||||
worldObj.newExplosion(this, posX, posY, posZ, config.explosive, config.incendiary > 0, config.blockDamage);
|
||||
|
||||
if(config.shrapnel > 0 && !worldObj.isRemote)
|
||||
ExplosionLarge.spawnShrapnels(worldObj, posX, posY, posZ, config.shrapnel);
|
||||
|
||||
if(config.chlorine > 0 && !worldObj.isRemote) {
|
||||
ExplosionChaos.spawnChlorine(worldObj, posX, posY, posZ, config.chlorine, 1.5, 0);
|
||||
worldObj.playSoundEffect((double)(posX + 0.5F), (double)(posY + 0.5F), (double)(posZ + 0.5F), "random.fizz", 5.0F, 2.6F + (rand.nextFloat() - rand.nextFloat()) * 0.8F);
|
||||
}
|
||||
|
||||
if(config.rainbow > 0 && !worldObj.isRemote) {
|
||||
EntityNukeExplosionMK3 ex = EntityNukeExplosionMK3.statFacFleija(worldObj, posX, posY, posZ, config.rainbow);
|
||||
if(!ex.isDead) {
|
||||
this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.explode", 100.0f, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
|
||||
worldObj.spawnEntityInWorld(ex);
|
||||
|
||||
EntityCloudFleijaRainbow cloud = new EntityCloudFleijaRainbow(this.worldObj, config.rainbow);
|
||||
cloud.posX = this.posX;
|
||||
cloud.posY = this.posY;
|
||||
cloud.posZ = this.posZ;
|
||||
this.worldObj.spawnEntityInWorld(cloud);
|
||||
}
|
||||
}
|
||||
|
||||
if(config.nuke > 0 && !worldObj.isRemote) {
|
||||
worldObj.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(worldObj, config.nuke, posX, posY, posZ).mute());
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "muke");
|
||||
if(MainRegistry.polaroidID == 11 || rand.nextInt(100) == 0) data.setBoolean("balefire", true);
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY + 0.5, posZ), new TargetPoint(dimension, posX, posY, posZ, 250));
|
||||
worldObj.playSoundEffect(posX, posY, posZ, "hbm:weapon.mukeExplosion", 15.0F, 1.0F);
|
||||
}
|
||||
|
||||
if(config.destroysBlocks && !worldObj.isRemote) {
|
||||
if(worldObj.getBlock(bX, bY, bZ).getBlockHardness(worldObj, bX, bY, bZ) <= 120)
|
||||
worldObj.func_147480_a(bX, bY, bZ, false);
|
||||
} else if(config.doesBreakGlass && !worldObj.isRemote) {
|
||||
if(worldObj.getBlock(bX, bY, bZ) == Blocks.glass ||
|
||||
worldObj.getBlock(bX, bY, bZ) == Blocks.glass_pane ||
|
||||
worldObj.getBlock(bX, bY, bZ) == Blocks.stained_glass ||
|
||||
worldObj.getBlock(bX, bY, bZ) == Blocks.stained_glass_pane)
|
||||
worldObj.func_147480_a(bX, bY, bZ, false);
|
||||
|
||||
if(worldObj.getBlock(bX, bY, bZ) == ModBlocks.red_barrel)
|
||||
((RedBarrel) ModBlocks.red_barrel).explode(worldObj, bX, bY, bZ);
|
||||
}
|
||||
}
|
||||
|
||||
//for when a bullet dies by hitting a block
|
||||
private void onRicochet(int bX, int bY, int bZ) {
|
||||
|
||||
if(config.bntRicochet != null)
|
||||
config.bntRicochet.behaveBlockRicochet(this, bX, bY, bZ);
|
||||
}
|
||||
|
||||
//for when a bullet dies by hitting an entity
|
||||
private void onEntityImpact(Entity e) {
|
||||
onEntityHurt(e);
|
||||
onBlockImpact(-1, -1, -1);
|
||||
|
||||
if(config.bntHit != null)
|
||||
config.bntHit.behaveEntityHit(this, e);
|
||||
}
|
||||
|
||||
//for when a bullet hurts an entity, not necessarily dying
|
||||
private void onEntityHurt(Entity e) {
|
||||
|
||||
if(config.bntHurt != null)
|
||||
config.bntHurt.behaveEntityHurt(this, e);
|
||||
|
||||
if(config.incendiary > 0 && !worldObj.isRemote) {
|
||||
e.setFire(config.incendiary);
|
||||
}
|
||||
|
||||
if(config.leadChance > 0 && !worldObj.isRemote && worldObj.rand.nextInt(100) < config.leadChance && e instanceof EntityLivingBase) {
|
||||
((EntityLivingBase)e).addPotionEffect(new PotionEffect(HbmPotion.lead.id, 10 * 20, 0));
|
||||
}
|
||||
|
||||
if(e instanceof EntityLivingBase && config.effects != null && !config.effects.isEmpty() && !worldObj.isRemote) {
|
||||
|
||||
for(PotionEffect effect : config.effects) {
|
||||
((EntityLivingBase)e).addPotionEffect(new PotionEffect(effect));
|
||||
}
|
||||
}
|
||||
|
||||
if(config.instakill && e instanceof EntityLivingBase && !worldObj.isRemote) {
|
||||
|
||||
if(!(e instanceof EntityPlayer && ((EntityPlayer)e).capabilities.isCreativeMode))
|
||||
((EntityLivingBase)e).setHealth(0.0F);
|
||||
}
|
||||
|
||||
if(config.caustic > 0 && e instanceof EntityPlayer){
|
||||
ArmorUtil.damageSuit((EntityPlayer)e, 0, config.caustic);
|
||||
ArmorUtil.damageSuit((EntityPlayer)e, 1, config.caustic);
|
||||
ArmorUtil.damageSuit((EntityPlayer)e, 2, config.caustic);
|
||||
ArmorUtil.damageSuit((EntityPlayer)e, 3, config.caustic);
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,12 +518,55 @@ public class EntityBulletBaseNT extends EntityThrowableInterp {
|
||||
public boolean isSpectral() {
|
||||
return this.config.isSpectral;
|
||||
}
|
||||
|
||||
public IBulletHurtBehavior bHurt;
|
||||
public IBulletHitBehavior bHit;
|
||||
public IBulletRicochetBehavior bRicochet;
|
||||
public IBulletImpactBehavior bImpact;
|
||||
public IBulletUpdateBehavior bUpdate;
|
||||
|
||||
@Override
|
||||
protected double headingForceMult() {
|
||||
return 1D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGravityVelocity() {
|
||||
return this.config.gravity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double motionMult() {
|
||||
return this.config.velocity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getAirDrag() {
|
||||
return 1F;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getWaterDrag() {
|
||||
return 1F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound nbt) {
|
||||
super.readEntityFromNBT(nbt);
|
||||
int cfg = nbt.getInteger("config");
|
||||
this.config = BulletConfigSyncingUtil.pullConfig(cfg);
|
||||
this.dataWatcher.updateObject(16, (byte)this.config.style);
|
||||
this.dataWatcher.updateObject(17, (byte)this.config.trail);
|
||||
|
||||
if(this.config == null) {
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
|
||||
this.overrideDamage = nbt.getFloat("damage");
|
||||
this.dataWatcher.updateObject(18, cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbt) {
|
||||
super.writeEntityToNBT(nbt);
|
||||
nbt.setInteger("config", dataWatcher.getWatchableObjectInt(18));
|
||||
nbt.setFloat("damage", this.overrideDamage);
|
||||
}
|
||||
|
||||
public interface IBulletHurtBehaviorNT { public void behaveEntityHurt(EntityBulletBaseNT bullet, Entity hit); }
|
||||
public interface IBulletHitBehaviorNT { public void behaveEntityHit(EntityBulletBaseNT bullet, Entity hit); }
|
||||
|
||||
@ -81,19 +81,27 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile {
|
||||
return 1.5F;
|
||||
}
|
||||
|
||||
protected double headingForceMult() {
|
||||
return 0.0075D;
|
||||
}
|
||||
|
||||
protected float throwAngle() {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
protected double motionMult() {
|
||||
return 1.0D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThrowableHeading(double motionX, double motionY, double motionZ, float velocity, float inaccuracy) {
|
||||
float throwLen = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);
|
||||
motionX /= (double) throwLen;
|
||||
motionY /= (double) throwLen;
|
||||
motionZ /= (double) throwLen;
|
||||
motionX += this.rand.nextGaussian() * 0.0075D * (double) inaccuracy;
|
||||
motionY += this.rand.nextGaussian() * 0.0075D * (double) inaccuracy;
|
||||
motionZ += this.rand.nextGaussian() * 0.0075D * (double) inaccuracy;
|
||||
motionX += this.rand.nextGaussian() * headingForceMult() * (double) inaccuracy;
|
||||
motionY += this.rand.nextGaussian() * headingForceMult() * (double) inaccuracy;
|
||||
motionZ += this.rand.nextGaussian() * headingForceMult() * (double) inaccuracy;
|
||||
motionX *= (double) velocity;
|
||||
motionY *= (double) velocity;
|
||||
motionZ *= (double) velocity;
|
||||
@ -155,11 +163,11 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile {
|
||||
++this.ticksInAir;
|
||||
|
||||
Vec3 pos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
|
||||
Vec3 nextPos = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
Vec3 nextPos = Vec3.createVectorHelper(this.posX + this.motionX * motionMult(), this.posY + this.motionY * motionMult(), this.posZ + this.motionZ * motionMult());
|
||||
MovingObjectPosition mop = null;
|
||||
if(!this.isSpectral()) mop = this.worldObj.rayTraceBlocks(pos, nextPos);
|
||||
pos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
|
||||
nextPos = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
nextPos = Vec3.createVectorHelper(this.posX + this.motionX * motionMult(), this.posY + this.motionY * motionMult(), this.posZ + this.motionZ * motionMult());
|
||||
|
||||
if(mop != null) {
|
||||
nextPos = Vec3.createVectorHelper(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
|
||||
@ -168,7 +176,7 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile {
|
||||
if(!this.worldObj.isRemote) {
|
||||
|
||||
Entity hitEntity = null;
|
||||
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX * motionMult(), this.motionY * motionMult(), this.motionZ * motionMult()).expand(1.0D, 1.0D, 1.0D));
|
||||
double nearest = 0.0D;
|
||||
EntityLivingBase thrower = this.getThrower();
|
||||
|
||||
@ -212,9 +220,9 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile {
|
||||
}
|
||||
}
|
||||
|
||||
this.posX += this.motionX;
|
||||
this.posY += this.motionY;
|
||||
this.posZ += this.motionZ;
|
||||
this.posX += this.motionX * motionMult();
|
||||
this.posY += this.motionY * motionMult();
|
||||
this.posZ += this.motionZ * motionMult();
|
||||
|
||||
float hyp = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
11
src/main/java/com/hbm/entity/projectile/IBulletBase.java
Normal file
11
src/main/java/com/hbm/entity/projectile/IBulletBase.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.hbm.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
import com.hbm.util.Tuple.Pair;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
public interface IBulletBase {
|
||||
public double prevX(); public double prevY(); public double prevZ();
|
||||
public void prevX(double d); public void prevY(double d); public void prevZ(double d);
|
||||
public List<Pair<Vec3, Double>> nodes();
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.hbm.handler;
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.entity.projectile.EntityBulletBase;
|
||||
import com.hbm.entity.projectile.EntityBulletBaseNT;
|
||||
import com.hbm.entity.projectile.EntityBulletBaseNT.*;
|
||||
import com.hbm.handler.guncfg.BulletConfigFactory;
|
||||
import com.hbm.interfaces.IBulletHitBehavior;
|
||||
@ -10,7 +11,6 @@ import com.hbm.interfaces.IBulletHurtBehavior;
|
||||
import com.hbm.interfaces.IBulletImpactBehavior;
|
||||
import com.hbm.interfaces.IBulletRicochetBehavior;
|
||||
import com.hbm.interfaces.IBulletUpdateBehavior;
|
||||
import com.hbm.interfaces.Untested;
|
||||
import com.hbm.inventory.RecipesCommon.ComparableStack;
|
||||
import com.hbm.lib.ModDamageSource;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -219,7 +219,6 @@ public class BulletConfiguration implements Cloneable {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Untested
|
||||
public DamageSource getDamage(EntityBulletBase bullet, EntityLivingBase shooter) {
|
||||
|
||||
DamageSource dmg;
|
||||
@ -242,6 +241,28 @@ public class BulletConfiguration implements Cloneable {
|
||||
return dmg;
|
||||
}
|
||||
|
||||
public DamageSource getDamage(EntityBulletBaseNT bullet, EntityLivingBase shooter) {
|
||||
|
||||
DamageSource dmg;
|
||||
|
||||
String unloc = damageType;
|
||||
|
||||
if(unloc.equals(ModDamageSource.s_zomg_prefix))
|
||||
unloc += (bullet.worldObj.rand.nextInt(5) + 1); //pain
|
||||
|
||||
if(shooter != null)
|
||||
dmg = new EntityDamageSourceIndirect(unloc, bullet, shooter);
|
||||
else
|
||||
dmg = new DamageSource(unloc);
|
||||
|
||||
if(this.dmgProj) dmg.setProjectile();
|
||||
if(this.dmgFire) dmg.setFireDamage();
|
||||
if(this.dmgExplosion) dmg.setExplosion();
|
||||
if(this.dmgBypass) dmg.setDamageBypassesArmor();
|
||||
|
||||
return dmg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BulletConfiguration clone() {
|
||||
try {
|
||||
|
||||
@ -6,6 +6,7 @@ import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.hbm.config.GeneralConfig;
|
||||
import com.hbm.entity.projectile.EntityBulletBase;
|
||||
import com.hbm.entity.projectile.EntityBulletBaseNT;
|
||||
import com.hbm.handler.BulletConfigSyncingUtil;
|
||||
import com.hbm.handler.BulletConfiguration;
|
||||
import com.hbm.handler.CasingEjector;
|
||||
@ -273,7 +274,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu
|
||||
//spawns the actual projectile, can be overridden to change projectile entity
|
||||
protected void spawnProjectile(World world, EntityPlayer player, ItemStack stack, int config) {
|
||||
|
||||
EntityBulletBase bullet = new EntityBulletBase(world, config, player);
|
||||
EntityBulletBaseNT bullet = new EntityBulletBaseNT(world, config, player);
|
||||
world.spawnEntityInWorld(bullet);
|
||||
|
||||
if(player instanceof EntityPlayerMP)
|
||||
|
||||
@ -548,6 +548,7 @@ public class ClientProxy extends ServerProxy {
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySchrab.class, new RenderFlare());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityBullet.class, new RenderRocket());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityBulletBase.class, new RenderBullet());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityBulletBaseNT.class, new RenderBullet());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, new RenderRainbow());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityNightmareBlast.class, new RenderOminousBullet());
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityFire.class, new RenderFireball(ModItems.energy_ball));
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.hbm.entity.projectile.EntityBulletBase;
|
||||
import com.hbm.entity.projectile.IBulletBase;
|
||||
import com.hbm.handler.BulletConfiguration;
|
||||
import com.hbm.items.ModItems;
|
||||
import com.hbm.lib.RefStrings;
|
||||
@ -71,7 +71,7 @@ public class RenderBullet extends Render {
|
||||
case BulletConfiguration.STYLE_APDS: renderAPDS(); break;
|
||||
case BulletConfiguration.STYLE_BLADE: renderBlade(); break;
|
||||
case BulletConfiguration.STYLE_BARREL: renderNuke(3); break;
|
||||
case BulletConfiguration.STYLE_TAU: renderTau((EntityBulletBase) bullet, trail, f1); break;
|
||||
case BulletConfiguration.STYLE_TAU: renderTau(bullet, trail, f1); break;
|
||||
default: renderBullet(trail); break;
|
||||
}
|
||||
|
||||
@ -482,7 +482,7 @@ public class RenderBullet extends Render {
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
private void renderTau(EntityBulletBase bullet, int trail, float interp) {
|
||||
private void renderTau(Entity bullet, int trail, float interp) {
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
@ -492,15 +492,17 @@ public class RenderBullet extends Render {
|
||||
double pY = bullet.prevPosY + (bullet.posY - bullet.prevPosY) * interp;
|
||||
double pZ = bullet.prevPosZ + (bullet.posZ - bullet.prevPosZ) * interp;
|
||||
|
||||
if(bullet.prevRenderY == 0) {
|
||||
bullet.prevRenderX = pX;
|
||||
bullet.prevRenderY = pY;
|
||||
bullet.prevRenderZ = pZ;
|
||||
IBulletBase iface = (IBulletBase) bullet;
|
||||
|
||||
if(iface.prevY() == 0) {
|
||||
iface.prevX(pX);
|
||||
iface.prevY(pY);
|
||||
iface.prevZ(pZ);
|
||||
}
|
||||
|
||||
double deltaX = bullet.prevRenderX - pX;
|
||||
double deltaY = bullet.prevRenderY - pY;
|
||||
double deltaZ = bullet.prevRenderZ - pZ;
|
||||
double deltaX = iface.prevX() - pX;
|
||||
double deltaY = iface.prevY() - pY;
|
||||
double deltaZ = iface.prevZ() - pZ;
|
||||
|
||||
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
|
||||
double dX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)interp;
|
||||
@ -521,7 +523,7 @@ public class RenderBullet extends Render {
|
||||
b = 1;
|
||||
}
|
||||
|
||||
for(Pair<Vec3, Double> pair : bullet.trailNodes) {
|
||||
for(Pair<Vec3, Double> pair : iface.nodes()) {
|
||||
Vec3 pos = pair.getKey();
|
||||
|
||||
double mult = 1D;
|
||||
@ -533,8 +535,8 @@ public class RenderBullet extends Render {
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0F, 1F, 0F);
|
||||
|
||||
for(int i = 0; i < bullet.trailNodes.size() - 1; i++) {
|
||||
final Pair<Vec3, Double> node = bullet.trailNodes.get(i), past = bullet.trailNodes.get(i + 1);
|
||||
for(int i = 0; i < iface.nodes().size() - 1; i++) {
|
||||
final Pair<Vec3, Double> node = iface.nodes().get(i), past = iface.nodes().get(i + 1);
|
||||
final Vec3 nodeLoc = node.getKey(), pastLoc = past.getKey();
|
||||
float nodeAlpha = node.getValue().floatValue();
|
||||
float pastAlpha = past.getValue().floatValue();
|
||||
@ -582,9 +584,9 @@ public class RenderBullet extends Render {
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glAlphaFunc(GL11.GL_GEQUAL, 0.1F);
|
||||
|
||||
bullet.prevRenderX = pX;
|
||||
bullet.prevRenderY = pY;
|
||||
bullet.prevRenderZ = pZ;
|
||||
iface.prevX(pX);
|
||||
iface.prevY(pY);
|
||||
iface.prevZ(pZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user