diff --git a/changelog b/changelog index 5d72f98ae..5e0b3f4d9 100644 --- a/changelog +++ b/changelog @@ -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 diff --git a/src/main/java/com/hbm/blocks/machine/MachineAssembler.java b/src/main/java/com/hbm/blocks/machine/MachineAssembler.java index a53437db9..eeaa0e63b 100644 --- a/src/main/java/com/hbm/blocks/machine/MachineAssembler.java +++ b/src/main/java/com/hbm/blocks/machine/MachineAssembler.java @@ -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; } diff --git a/src/main/java/com/hbm/entity/EntityMappings.java b/src/main/java/com/hbm/entity/EntityMappings.java index 9e3d2919f..49b065651 100644 --- a/src/main/java/com/hbm/entity/EntityMappings.java +++ b/src/main/java/com/hbm/entity/EntityMappings.java @@ -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); diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java index 6ebfd313a..e0c8fdb92 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java @@ -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> nodes() { return this.trailNodes; } private BulletConfiguration config; public EntityLivingBase shooter; diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java index d793af58d..a3ce55d10 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java @@ -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> 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); } diff --git a/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java b/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java index 8136defa8..ca5a551b2 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java +++ b/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java @@ -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); diff --git a/src/main/java/com/hbm/entity/projectile/IBulletBase.java b/src/main/java/com/hbm/entity/projectile/IBulletBase.java new file mode 100644 index 000000000..635ce9a09 --- /dev/null +++ b/src/main/java/com/hbm/entity/projectile/IBulletBase.java @@ -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> nodes(); +} diff --git a/src/main/java/com/hbm/handler/BulletConfiguration.java b/src/main/java/com/hbm/handler/BulletConfiguration.java index 53ebc9546..fe3745bc5 100644 --- a/src/main/java/com/hbm/handler/BulletConfiguration.java +++ b/src/main/java/com/hbm/handler/BulletConfiguration.java @@ -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 { diff --git a/src/main/java/com/hbm/items/weapon/ItemGunBase.java b/src/main/java/com/hbm/items/weapon/ItemGunBase.java index c6b2625ef..930366673 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunBase.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunBase.java @@ -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) diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index a3b34fa22..062c70bda 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -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)); diff --git a/src/main/java/com/hbm/render/entity/projectile/RenderBullet.java b/src/main/java/com/hbm/render/entity/projectile/RenderBullet.java index 0c8f15481..d8c59d98f 100644 --- a/src/main/java/com/hbm/render/entity/projectile/RenderBullet.java +++ b/src/main/java/com/hbm/render/entity/projectile/RenderBullet.java @@ -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 pair : bullet.trailNodes) { + for(Pair 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 node = bullet.trailNodes.get(i), past = bullet.trailNodes.get(i + 1); + for(int i = 0; i < iface.nodes().size() - 1; i++) { + final Pair 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