bullet damage, armor pen, durability stats

This commit is contained in:
Boblet 2024-09-25 16:45:42 +02:00
parent 1d92bcbf13
commit 0f277657db
12 changed files with 141 additions and 30 deletions

View File

@ -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
* The conveyor grabber should no longer skip over items when used in long lines
* Fixed a potential crash regarding crucibles

View File

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

View File

@ -211,7 +211,7 @@ public class Mats {
List<MaterialStack> 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) {

View File

@ -37,6 +37,8 @@ public abstract class SerializableRecipe {
public static final Gson gson = new Gson();
public static List<SerializableRecipe> 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();

View File

@ -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<EntityBulletBaseMK4, Float> 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;
}
}

View File

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

View File

@ -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<ItemStack, AnimType, BusAnimation> LAMBDA_DEBUG_ANIMS = (stack, type) -> {
switch(type) {

View File

@ -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()

View File

@ -246,6 +246,7 @@ public class MainRegistry {
@EventHandler
public void PreLoad(FMLPreInitializationEvent PreEvent) {
CrashHelper.init();
startupTime = System.currentTimeMillis();
configDir = PreEvent.getModConfigurationDirectory();

View File

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

View File

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

View File

@ -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}]},