diff --git a/changelog b/changelog index 9786bc247..dd831e3fd 100644 --- a/changelog +++ b/changelog @@ -6,4 +6,5 @@ * Tom's explosion no longer causes any block updates on the millions of blocks it deletes which hopefully fixes a majority of the lag caused by the crater ## Fixed -* The conveyor grabber should no longer skip over items when used in long lines \ No newline at end of file +* The conveyor grabber should no longer skip over items when used in long lines +* Fixed a potential crash regarding crucibles \ No newline at end of file diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java index d9760ba2f..0e23f25c4 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java @@ -1,15 +1,13 @@ package com.hbm.entity.projectile; import com.hbm.items.weapon.sedna.BulletConfig; -import com.hbm.lib.ModDamageSource; -import com.hbm.packet.PacketDispatcher; -import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.util.BobMathUtil; +import com.hbm.util.EntityDamageUtil; import com.hbm.util.TrackerUtil; -import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; @@ -20,8 +18,10 @@ import net.minecraftforge.common.util.ForgeDirection; public class EntityBulletBaseMK4 extends EntityThrowableInterp { public BulletConfig config; + //used for rendering tracers public double velocity; public double prevVelocity; + public float damage; public int ricochets = 0; public EntityBulletBaseMK4(World world) { @@ -30,12 +30,14 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp { this.setSize(0.5F, 0.5F); } - public EntityBulletBaseMK4(EntityLivingBase entity, BulletConfig config, float baseDamage, float spreadMod, double sideOffset, double heightOffset, double frontOffset) { + public EntityBulletBaseMK4(EntityLivingBase entity, BulletConfig config, float baseDamage, float gunSpread, double sideOffset, double heightOffset, double frontOffset) { this(entity.worldObj); this.thrower = entity; this.config = 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); @@ -52,7 +54,7 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp { 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 * spreadMod); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread + gunSpread); } @Override @@ -155,18 +157,32 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp { } if(mop.typeOfHit == mop.typeOfHit.ENTITY) { - if(!mop.entityHit.isEntityAlive()) return; + Entity entity = mop.entityHit; + if(!entity.isEntityAlive()) return; - if(mop.entityHit.isEntityAlive()) { - mop.entityHit.attackEntityFrom(ModDamageSource.turbofan, 1_000F); - - NBTTagCompound vdat = new NBTTagCompound(); - vdat.setString("type", "giblets"); - vdat.setInteger("ent", mop.entityHit.getEntityId()); - vdat.setInteger("cDiv", 2); - PacketDispatcher.wrapper.sendToAllAround( - new AuxParticlePacketNT(vdat, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ), - new TargetPoint(this.dimension, mop.entityHit.posX, mop.entityHit.posY + mop.entityHit.height * 0.5, mop.entityHit.posZ, 150)); + DamageSource damageCalc = this.config.getDamage(this, getThrower(), false); + + if(!(entity instanceof EntityLivingBase)) { + entity.attackEntityFrom(damageCalc, this.damage); + return; + } + + EntityLivingBase living = (EntityLivingBase) entity; + float prevHealth = living.getHealth(); + + if(this.config.armorPiercingPercent == 0) { + EntityDamageUtil.attackEntityFromIgnoreIFrame(entity, damageCalc, this.damage); + } else { + DamageSource damagePiercing = this.config.getDamage(this, getThrower(), true); + EntityDamageUtil.attackArmorPiercing(living, damageCalc, damagePiercing, this.damage, this.config.armorPiercingPercent); + } + + float newHealth = living.getHealth(); + + if(this.config.damageFalloffByPen) this.damage -= Math.max(prevHealth - newHealth, 0); + if(!this.doesPenetrate() || this.damage < 0) { + this.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord); + this.setDead(); } } } @@ -177,4 +193,9 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp { @Override protected double motionMult() { return this.config.velocity; } @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; } } diff --git a/src/main/java/com/hbm/inventory/material/Mats.java b/src/main/java/com/hbm/inventory/material/Mats.java index 8879a622e..3739f9fd1 100644 --- a/src/main/java/com/hbm/inventory/material/Mats.java +++ b/src/main/java/com/hbm/inventory/material/Mats.java @@ -211,7 +211,7 @@ public class Mats { List entries = materialEntries.get(new ComparableStack(stack).makeSingular()); if(entries != null) { - list.addAll(entries); + entries.forEach(x -> { if(x != null) list.add(x); }); } if(stack.getItem() == ModItems.scraps) { diff --git a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java index ab0d5e9cf..bbcbceb5a 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -37,6 +37,8 @@ public abstract class SerializableRecipe { public static final Gson gson = new Gson(); public static List recipeHandlers = new ArrayList(); + public boolean modified = false; + /* * INIT */ @@ -100,6 +102,7 @@ public abstract class SerializableRecipe { if(recFile.exists() && recFile.isFile()) { MainRegistry.logger.info("Reading recipe file " + recFile.getName()); recipe.readRecipeFile(recFile); + recipe.modified = true; } else { MainRegistry.logger.info("No recipe file found, registering defaults for " + recipe.getFileName()); recipe.registerDefaults(); @@ -107,6 +110,7 @@ public abstract class SerializableRecipe { File recTemplate = new File(recDir.getAbsolutePath() + File.separatorChar + "_" + recipe.getFileName()); MainRegistry.logger.info("Writing template file " + recTemplate.getName()); recipe.writeTemplateFile(recTemplate); + recipe.modified = false; } recipe.registerPost(); diff --git a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java index acfcc783c..4cf10e425 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java +++ b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java @@ -8,9 +8,13 @@ import com.hbm.entity.projectile.EntityBulletBaseMK4; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmo; +import com.hbm.lib.ModDamageSource; import com.hbm.particle.SpentCasing; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.Item; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EntityDamageSourceIndirect; public class BulletConfig { @@ -19,6 +23,7 @@ public class BulletConfig { public final int id; public ComparableStack ammo; + /** How much ammo is added to a standard mag when loading one item */ public int ammoReloadCount = 1; public float velocity = 10F; public float spread = 0F; @@ -30,11 +35,24 @@ public class BulletConfig { public float armorPiercingPercent = 0.0F; public float headshotMult = 1.0F; + public String damageType = ModDamageSource.s_bullet; + public boolean dmgProj = true; + public boolean dmgFire = false; + public boolean dmgExplosion = false; + public boolean dmgBypass = false; + public float ricochetAngle = 5F; public int maxRicochetCount = 2; + /** Whether damage dealt to an entity is subtracted from the projectile's damage on penetration */ + public boolean damageFalloffByPen = true; public double gravity = 0; - public int expires = 100; + public int expires = 30; + public boolean impactsEntities = true; + public boolean doesPenetrate = false; + /** Whether projectiles ignore blocks entirely */ + public boolean isSpectral = false; + public int selfDamageDelay = 2; public boolean renderRotations = true; public SpentCasing casing; @@ -55,11 +73,33 @@ public class BulletConfig { public BulletConfig setDamage(float damageMult) { this.damageMult = damageMult; return this; } public BulletConfig setArmorPiercing(float armorPiercingPercent) { this.armorPiercingPercent = armorPiercingPercent; return this; } public BulletConfig setHeadshot(float headshotMult) { this.headshotMult = headshotMult; return this; } + public BulletConfig setDamageType(String type) { this.damageType = type; return this; } + public BulletConfig setupDamageClass(boolean proj, boolean fire, boolean explosion, boolean bypass) { this.dmgProj = proj; this.dmgFire = fire; this.dmgExplosion = explosion; this.dmgBypass = bypass; return this; } public BulletConfig setRicochetAngle(float angle) { this.ricochetAngle = angle; return this; } public BulletConfig setRicochetCount(int count) { this.maxRicochetCount = count; return this; } + public BulletConfig setDamageFalloutByPen(boolean falloff) { this.damageFalloffByPen = falloff; return this; } public BulletConfig setGrav(double gravity) { this.gravity = gravity; return this; } public BulletConfig setLife(int expires) { this.expires = expires; return this; } + public BulletConfig setImpactsEntities(boolean impact) { this.impactsEntities = impact; return this; } + public BulletConfig setDoesPenetrate(boolean pen) { this.doesPenetrate = pen; return this; } + public BulletConfig setSpectral(boolean spectral) { this.isSpectral = spectral; return this; } + public BulletConfig setSelfDamageDelay(int delay) { this.selfDamageDelay = delay; return this; } public BulletConfig setRenderRotations(boolean rot) { this.renderRotations = rot; return this; } public BulletConfig setCasing(SpentCasing casing) { this.casing = casing; return this; } public BulletConfig setRenderer(BiConsumer renderer) { this.renderer = renderer; return this; } + + public DamageSource getDamage(EntityBulletBaseMK4 bullet, EntityLivingBase shooter, boolean bypass) { + + DamageSource dmg; + + if(shooter != null) dmg = new EntityDamageSourceIndirect(damageType, bullet, shooter); + else dmg = new DamageSource(damageType); + + if(this.dmgProj) dmg.setProjectile(); + if(this.dmgFire) dmg.setFireDamage(); + if(this.dmgExplosion) dmg.setExplosion(); + if(this.dmgBypass || bypass) dmg.setDamageBypassesArmor(); + + return dmg; + } } diff --git a/src/main/java/com/hbm/items/weapon/sedna/Receiver.java b/src/main/java/com/hbm/items/weapon/sedna/Receiver.java index 3d700eca0..9134b759a 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/Receiver.java +++ b/src/main/java/com/hbm/items/weapon/sedna/Receiver.java @@ -58,7 +58,7 @@ public class Receiver { public float getBaseDamage(ItemStack stack) { return WeaponUpgradeManager.eval(this.baseDamage_DNA, stack, F_BASEDAMAGE, this); } public int getDelayAfterFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterFire_DNA, stack, I_DELAYAFTERFIRE, this); } public int getRoundsPerCycle(ItemStack stack) { return WeaponUpgradeManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); } - public float getSpreadMod(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadModExtra_DNA, stack, F_SPREADMOD, this); } + public float getGunSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadModExtra_DNA, stack, F_SPREADMOD, this); } public boolean getRefireOnHold(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); } public boolean getDoesDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.doesDryFire_DNA, stack, B_DOESDRYFIRE, this); } public CasingEjector getEjector(ItemStack stack) { return WeaponUpgradeManager.eval(this.ejector_DNA, stack, O_EJECTOR, this); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java b/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java index 817b4bfef..8cef4e3ac 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java @@ -6,6 +6,7 @@ import java.util.function.BiFunction; import com.hbm.entity.projectile.EntityBulletBaseMK4; import com.hbm.items.weapon.sedna.BulletConfig; +import com.hbm.items.weapon.sedna.GunConfig; import com.hbm.items.weapon.sedna.ItemGunBaseNT; import com.hbm.items.weapon.sedna.ItemGunBaseNT.GunState; import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext; @@ -112,14 +113,28 @@ public class Lego { if(config.projectilesMax > config.projectilesMin) projectiles += player.getRNG().nextInt(config.projectilesMax - config.projectilesMin + 1); for(int i = 0; i < projectiles; i++) { - EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(player, config, primary.getBaseDamage(stack), primary.getSpreadMod(stack) * aim + 1F, sideOffset, -0.0625, 0.75); + float damage = primary.getBaseDamage(stack) * getStandardWearDamage(stack, ctx.config); + float spread = primary.getGunSpread(stack) * aim + getStandardWearSpread(stack, ctx.config) * 0.125F; + EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(player, config, damage, spread, sideOffset, -0.0625, 0.75); player.worldObj.spawnEntityInWorld(mk4); } mag.setAmount(stack, mag.getAmount(stack) - 1); - ItemGunBaseNT.setWear(stack, ItemGunBaseNT.getWear(stack) + config.wear); + ItemGunBaseNT.setWear(stack, Math.min(ItemGunBaseNT.getWear(stack) + config.wear, ctx.config.getDurability(stack))); }; + public static float getStandardWearSpread(ItemStack stack, GunConfig config) { + float percent = (float) ItemGunBaseNT.getWear(stack) / config.getDurability(stack); + if(percent < 0.5F) return 0F; + return (percent - 0.5F) * 2F; + } + + public static float getStandardWearDamage(ItemStack stack, GunConfig config) { + float percent = (float) ItemGunBaseNT.getWear(stack) / config.getDurability(stack); + if(percent < 0.75F) return 1F; + return 1F - (percent - 0.75F) * 2F; + } + /** anims for the DEBUG revolver, mostly a copy of the li'lpip but with some fixes regarding the cylinder movement */ @SuppressWarnings("incomplete-switch") public static BiFunction LAMBDA_DEBUG_ANIMS = (stack, type) -> { switch(type) { diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java index d783d5810..f5b21e6ae 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java @@ -23,7 +23,7 @@ public class XFactoryBlackPowder { public static void init() { BulletConfig stone = new BulletConfig().setItem(EnumAmmo.STONE).setSpread(0.025F).setRicochetAngle(15); - BulletConfig flint = new BulletConfig().setItem(EnumAmmo.STONE_AP).setSpread(0.01F).setRicochetAngle(5); + BulletConfig flint = new BulletConfig().setItem(EnumAmmo.STONE_AP).setSpread(0.01F).setRicochetAngle(5).setDoesPenetrate(true).setDamage(1.5F); BulletConfig shot = new BulletConfig().setItem(EnumAmmo.STONE_SHOT).setSpread(0.1F).setRicochetAngle(45).setProjectiles(6, 6).setDamage(0.2F); ModItems.gun_pepperbox = new ItemGunBaseNT(new GunConfig() diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index acdda9f2e..d2d5155ad 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -246,6 +246,7 @@ public class MainRegistry { @EventHandler public void PreLoad(FMLPreInitializationEvent PreEvent) { + CrashHelper.init(); startupTime = System.currentTimeMillis(); configDir = PreEvent.getModConfigurationDirectory(); diff --git a/src/main/java/com/hbm/util/CrashHelper.java b/src/main/java/com/hbm/util/CrashHelper.java new file mode 100644 index 000000000..ed5198932 --- /dev/null +++ b/src/main/java/com/hbm/util/CrashHelper.java @@ -0,0 +1,33 @@ +package com.hbm.util; + +import com.hbm.inventory.recipes.loader.SerializableRecipe; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.ICrashCallable; + +public class CrashHelper { + + public static void init() { + FMLCommonHandler.instance().registerCrashCallable(new CrashCallableRecipe()); + } + + public static class CrashCallableRecipe implements ICrashCallable { + + @Override + public String getLabel() { + return "NTM Modified recipes:"; + } + + @Override + public String call() throws Exception { + + String call = ""; + + for(SerializableRecipe rec : SerializableRecipe.recipeHandlers) { + if(rec.modified) call += "\n\t\t" + rec.getFileName(); + } + + return call; + } + } +} diff --git a/src/main/java/com/hbm/util/EntityDamageUtil.java b/src/main/java/com/hbm/util/EntityDamageUtil.java index 1e5b3a623..ada2a10c8 100644 --- a/src/main/java/com/hbm/util/EntityDamageUtil.java +++ b/src/main/java/com/hbm/util/EntityDamageUtil.java @@ -67,7 +67,7 @@ public class EntityDamageUtil { //damage removed by the calculation float reduced = Math.max(amount - afterTax, 0F); //damage that would pass + damage tthat wouldn't pass * AP percentage - return living.attackEntityFrom(sourceArmorPiercing, Math.max(afterTax + (reduced * piercing), 0F)); + return attackEntityFromIgnoreIFrame(living, sourceArmorPiercing, Math.max(afterTax + (reduced * piercing), 0F)); } diff --git a/src/main/resources/assets/hbm/sounds.json b/src/main/resources/assets/hbm/sounds.json index 2943195e5..be68ebfef 100644 --- a/src/main/resources/assets/hbm/sounds.json +++ b/src/main/resources/assets/hbm/sounds.json @@ -295,10 +295,6 @@ "potatos.random": {"category": "player", "sounds": ["potatos/randResponse0", "potatos/randResponse1", "potatos/randResponse2", "potatos/randResponse3", "potatos/randResponse4", "potatos/randResponse5", "potatos/randResponse6", "potatos/randResponse7"]}, - "fm.clap": {"category": "block", "sounds": [{"name": "clap", "stream": false}]}, - "fm.mug": {"category": "block", "sounds": [{"name": "mug", "stream": false}]}, - "fm.sample": {"category": "block", "sounds": [{"name": "sample", "stream": false}]}, - "alarm.amsSiren": {"category": "record", "sounds": [{"name": "alarm/amsSiren", "stream": false}]}, "alarm.apcLoop": {"category": "record", "sounds": [{"name": "alarm/apcLoop", "stream": false}]}, "alarm.apcPass": {"category": "record", "sounds": [{"name": "alarm/apcPass", "stream": false}]},