From 02d749bdb11cb6f16bfa37176cb1407ff52e0ccf Mon Sep 17 00:00:00 2001 From: Boblet Date: Fri, 24 Jan 2025 14:57:21 +0100 Subject: [PATCH] spread it --- changelog | 2 ++ .../projectile/EntityBulletBaseMK4.java | 4 ++-- .../com/hbm/items/weapon/sedna/Receiver.java | 20 ++++++++++++---- .../hbm/items/weapon/sedna/factory/Lego.java | 23 +++++++++++-------- .../weapon/sedna/factory/XFactory10ga.java | 2 +- .../weapon/sedna/factory/XFactory12ga.java | 6 ++--- .../sedna/factory/XFactoryAccelerator.java | 3 +-- 7 files changed, 38 insertions(+), 22 deletions(-) diff --git a/changelog b/changelog index 438300216..9e947bed6 100644 --- a/changelog +++ b/changelog @@ -9,6 +9,8 @@ * Changed fuel stats for HEAus, it's now a linear fuel with a multiplier of 35 with a heat/flux of 1.5°C * Digamma RBMK fuel now lasts substantially longer * RBMK dials now have gamerules for disabling rod depletion and xenon poison +* Changed the way bullet spread is calculated. For most guns, the effective spread will be the same, however this paves the way for better spread control via weapon mods, and also changes a few existing weapons + * All sawed-off shotguns (dual shotguns, Broken, Sacred Dragon) now have more spread with shot (+35%), while slugs remain the same ## Fixed * Fixed incorrect tooltip in the automatic control rod's GUI diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java index 29b0ce553..fac0c3037 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseMK4.java @@ -78,7 +78,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 + gunSpread); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, gunSpread); } /** For turrets - angles are in radians, and pitch is negative! */ @@ -94,7 +94,7 @@ public class EntityBulletBaseMK4 extends EntityThrowableInterp { this.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI); this.motionZ = MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI); this.motionY = (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI)); - this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, this.config.spread + gunSpread); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.0F, gunSpread); } @Override 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 df3b0816e..fecec6809 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/Receiver.java +++ b/src/main/java/com/hbm/items/weapon/sedna/Receiver.java @@ -22,7 +22,10 @@ public class Receiver { public static final String I_DELAYAFTERFIRE = "I_DELAYAFTERFIRE"; public static final String I_DELAYAFTERDRYFIRE = "I_DELAYAFTERDRYFIRE"; public static final String I_ROUNDSPERCYCLE = "I_ROUNDSPERCYCLE"; - public static final String F_SPREADMOD = "F_SPREADMOD"; + public static final String F_SPRADINNATE = "F_SPRADINNATE"; + public static final String F_SPREADAMMO = "F_SPREADAMMO"; + public static final String F_SPREADHIPFIRE = "F_SPREADHIPFIRE"; + public static final String F_SPREADDURABILITY = "F_SPREADDURABILITY"; public static final String B_REFIREONHOLD = "B_REFIREONHOLD"; public static final String B_REFIREAFTERDRY = "B_REFIREAFTERDRY"; public static final String B_DOESDRYFIRE = "B_DOESDRYFIRE"; @@ -54,7 +57,10 @@ public class Receiver { protected int delayAfterFire_DNA; protected int delayAfterDryFire_DNA; protected int roundsPerCycle_DNA = 1; - protected float spreadModExtra_DNA = 0F; + protected float spreadInnate_DNA = 0F; + protected float spreadMultAmmo_DNA = 1F; + protected float spreadPenaltyHipfire_DNA = 0.05F; + protected float spreadDurability_DNA = 0.125F; protected boolean refireOnHold_DNA = false; protected boolean refireAfterDry_DNA = false; protected boolean doesDryFire_DNA = true; @@ -82,7 +88,10 @@ public class Receiver { public int getDelayAfterFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterFire_DNA, stack, I_DELAYAFTERFIRE, this); } public int getDelayAfterDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.delayAfterDryFire_DNA, stack, I_DELAYAFTERDRYFIRE, this); } public int getRoundsPerCycle(ItemStack stack) { return WeaponUpgradeManager.eval(this.roundsPerCycle_DNA, stack, I_ROUNDSPERCYCLE, this); } - public float getGunSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadModExtra_DNA, stack, F_SPREADMOD, this); } + public float getInnateSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadInnate_DNA, stack, F_SPRADINNATE, this); } + public float getAmmoSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadMultAmmo_DNA, stack, F_SPREADAMMO, this); } + public float getHipfireSpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadPenaltyHipfire_DNA, stack, F_SPREADHIPFIRE, this); } + public float getDurabilitySpread(ItemStack stack) { return WeaponUpgradeManager.eval(this.spreadDurability_DNA, stack, F_SPREADDURABILITY, this); } public boolean getRefireOnHold(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireOnHold_DNA, stack, B_REFIREONHOLD, this); } public boolean getRefireAfterDry(ItemStack stack) { return WeaponUpgradeManager.eval(this.refireAfterDry_DNA, stack, B_REFIREAFTERDRY, this); } public boolean getDoesDryFire(ItemStack stack) { return WeaponUpgradeManager.eval(this.doesDryFire_DNA, stack, B_DOESDRYFIRE, this); } @@ -111,7 +120,10 @@ public class Receiver { public Receiver delay(int delay) { this.delayAfterFire_DNA = this.delayAfterDryFire_DNA = delay; return this; } public Receiver dry(int delay) { this.delayAfterDryFire_DNA = delay; return this; } public Receiver rounds(int rounds) { this.roundsPerCycle_DNA = rounds; return this; } - public Receiver spread(float spread) { this.spreadModExtra_DNA = spread; return this; } + public Receiver spread(float spread) { this.spreadInnate_DNA = spread; return this; } + public Receiver spreadAmmo(float spread) { this.spreadMultAmmo_DNA = spread; return this; } + public Receiver spreadHipfire(float spread) { this.spreadPenaltyHipfire_DNA = spread; return this; } + public Receiver spreadDurability(float spread) { this.spreadDurability_DNA = spread; return this; } public Receiver auto(boolean auto) { this.refireOnHold_DNA = auto; return this; } public Receiver autoAfterDry(boolean auto) { this.refireAfterDry_DNA = auto; return this; } public Receiver dryfire(boolean dryfire) { this.doesDryFire_DNA = dryfire; return 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 1613291de..693180de3 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 @@ -201,7 +201,7 @@ public class Lego { int index = ctx.configIndex; if(anim != null) ItemGunBaseNT.playAnimation(player, stack, anim, ctx.configIndex); - float aim = ItemGunBaseNT.getIsAiming(stack) ? 0.25F : 1F; + boolean aim = ItemGunBaseNT.getIsAiming(stack); Receiver primary = ctx.config.getReceivers(stack)[0]; IMagazine mag = primary.getMagazine(stack); BulletConfig config = (BulletConfig) mag.getType(stack, ctx.inventory); @@ -220,7 +220,7 @@ public class Lego { for(int i = 0; i < projectiles; i++) { float damage = calcDamage(ctx, stack, primary, calcWear, index); - float spread = calcSpread(ctx, stack, primary, calcWear, index, aim); + float spread = calcSpread(ctx, stack, primary, config, calcWear, index, aim); if(config.pType == ProjectileType.BULLET) { EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(entity, config, damage, spread, sideOffset, heightOffset, forwardOffset); @@ -260,14 +260,17 @@ public class Lego { return primary.getBaseDamage(stack) * (calcWear ? getStandardWearDamage(stack, ctx.config, index) : 1); } - public static float calcSpread(LambdaContext ctx, ItemStack stack, Receiver primary, boolean calcWear, int index, float aim) { - return primary.getGunSpread(stack) * aim + (calcWear ? getStandardWearSpread(stack, ctx.config, index) * 0.125F : 0F); //TODO: redo all this spread shit - /* - * spread should have multiple additive parts: - * - hipfire penalty (mitigated by aiming) - * - innate gun inaccuracy (usually 0, increases with wear) - * - bullet inaccuray (usually 0, higher with buckshot) - */ + public static float calcSpread(LambdaContext ctx, ItemStack stack, Receiver primary, BulletConfig config, boolean calcWear, int index, boolean aim) { + // the gun's innate spread, SMGs will have poor accuracy no matter what + float spreadInnate = primary.getInnateSpread(stack); + // the ammo's spread (for example for buckshot) multiplied with the gun's ammo modifier (choke or sawed off barrel) + float spreadAmmo = config.spread * primary.getAmmoSpread(stack); + // hipfire penalty, i.e. extra spread when not aiming + float spreadHipfire = aim ? 0F : primary.getHipfireSpread(stack); + // extra spread caused by weapon durability, [0;0.125] by default + float spreadWear = !calcWear ? 0F : (getStandardWearSpread(stack, ctx.config, index) * primary.getDurabilitySpread(stack)); + + return spreadInnate + spreadAmmo + spreadHipfire + spreadWear; } public static void standardExplode(EntityBulletBaseMK4 bullet, MovingObjectPosition mop, float range) { standardExplode(bullet, mop, range, 1F); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory10ga.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory10ga.java index 9df3a3a63..380c1d177 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory10ga.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory10ga.java @@ -49,7 +49,7 @@ public class XFactory10ga { ModItems.gun_double_barrel_sacred_dragon = new ItemGunBaseNT(WeaponQuality.B_SIDE, new GunConfig() .dura(6000).draw(10).inspect(39).crosshair(Crosshair.L_CIRCLE).smoke(Lego.LAMBDA_STANDARD_SMOKE) .rec(new Receiver(0) - .dmg(45F).rounds(2).delay(10).reload(41).reloadOnEmpty(true).sound("hbm:weapon.fire.shotgun", 1.0F, 0.9F) + .dmg(45F).spreadAmmo(1.35F).rounds(2).delay(10).reload(41).reloadOnEmpty(true).sound("hbm:weapon.fire.shotgun", 1.0F, 0.9F) .mag(new MagazineFullReload(0, 2).addConfigs(g10, g10_shrapnel, g10_du, g10_slug)) .offset(0.75, -0.0625, -0.1875) .setupStandardFire().recoil(LAMBDA_RECOIL_DOUBLE_BARREL)) diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java index d62c65262..a0ee792ba 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java @@ -297,7 +297,7 @@ public class XFactory12ga { ModItems.gun_maresleg_akimbo = new ItemGunBaseNT(WeaponQuality.B_SIDE, new GunConfig().dura(600).draw(5).inspect(39).reloadSequential(true).crosshair(Crosshair.L_CIRCLE).smoke(Lego.LAMBDA_STANDARD_SMOKE) .rec(new Receiver(0) - .dmg(16F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) + .dmg(16F).spreadAmmo(1.35F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) .mag(new MagazineSingleReload(0, 6).addConfigs(all)) .offset(0.75, -0.0625, 0.1875D) .setupStandardFire().recoil(LAMBDA_RECOIL_MARESLEG)) @@ -306,7 +306,7 @@ public class XFactory12ga { .anim(LAMBDA_MARESLEG_SHORT_ANIMS).orchestra(Orchestras.ORCHESTRA_MARESLEG_AKIMBO), new GunConfig().dura(600).draw(5).inspect(39).reloadSequential(true).crosshair(Crosshair.L_CIRCLE).smoke(Lego.LAMBDA_STANDARD_SMOKE) .rec(new Receiver(0) - .dmg(16F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) + .dmg(16F).spreadAmmo(1.35F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) .mag(new MagazineSingleReload(1, 6).addConfigs(all)) .offset(0.75, -0.0625, -0.1875) .setupStandardFire().recoil(LAMBDA_RECOIL_MARESLEG)) @@ -317,7 +317,7 @@ public class XFactory12ga { ModItems.gun_maresleg_broken = new ItemGunBaseNT(WeaponQuality.LEGENDARY, new GunConfig() .dura(0).draw(5).inspect(39).reloadSequential(true).crosshair(Crosshair.L_CIRCLE).smoke(Lego.LAMBDA_STANDARD_SMOKE) .rec(new Receiver(0) - .dmg(32F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) + .dmg(32F).spreadAmmo(1.35F).delay(20).reload(22, 10, 13, 0).jam(24).sound("hbm:weapon.fire.shotgun", 1.0F, 1.0F) .mag(new MagazineSingleReload(0, 6).addConfigs(g12_equestrian_tkr, g12_bp, g12_bp_magnum, g12_bp_slug, g12, g12_slug, g12_flechette, g12_magnum, g12_explosive, g12_phosphorus)) .offset(0.75, -0.0625, -0.1875) .canFire(Lego.LAMBDA_STANDARD_CAN_FIRE).fire(Lego.LAMBDA_NOWEAR_FIRE).recoil(LAMBDA_RECOIL_MARESLEG)) diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryAccelerator.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryAccelerator.java index f8a2d8769..e14868f94 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryAccelerator.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryAccelerator.java @@ -143,7 +143,6 @@ public class XFactoryAccelerator { EntityLivingBase entity = ctx.entity; int index = ctx.configIndex; - float aim = ItemGunBaseNT.getIsAiming(stack) ? 0.25F : 1F; Receiver primary = ctx.config.getReceivers(stack)[0]; BulletConfig config = tauChargeMag.getFirstConfig(stack, ctx.inventory); @@ -153,7 +152,7 @@ public class XFactoryAccelerator { double sideOffset = offset.zCoord; float damage = Lego.getStandardWearDamage(stack, ctx.config, index) * unitsUsed * 5; - float spread = Lego.calcSpread(ctx, stack, primary, true, index, aim); + float spread = Lego.calcSpread(ctx, stack, primary, config, true, index, false); EntityBulletBeamBase mk4 = new EntityBulletBeamBase(entity, config, damage, spread, sideOffset, heightOffset, forwardOffset); entity.worldObj.spawnEntityInWorld(mk4);