From 4122a9d51d655134225cb26a0c193eb51adc226c Mon Sep 17 00:00:00 2001 From: SomeonesShade Date: Thu, 1 Jan 2026 03:39:22 +0800 Subject: [PATCH] Reactivity and Assorted Changes (#11245) * Implemented turretDepositCooldown (1) * Implemented activationTime for Turrets (1) * activationTime for Turrets Fixes (2) readSync() line isn't needed, Overdrive should not make the cooldown go faster, it stays as is unless there is a good argument against it. * activationTime (3): Descriptions and SetBars() Updated arc and lancer descriptions. Added setBars() stuff for clearness. * turretDepositCooldown (2): now depositCooldown and is now on a per turret basis if needed... will potentially need further iteration * turretDepositCooldown (3): made it opt in added an internal gamerule (long name, need to reduce it later) to enable the balance (oriented for pvp) depositCooldown = 0 by def added depositCooldown entries in Blocks.java * activationTime (4): Minor Adjustments to UI * activitationTime (5): Implemented drawInactive() and inactiveColo, and arc/lancer sprite Thinking if I should set the sprites to be white, then use Color.gray... * turretDepositCooldown (4): Made the cooldown only affect turrets * Reload Turret Coolant Fixes (1) Made coolant and overdrive effects not get chopped off from Math.min when its too high * activationTime (6): activationTime is now at the Base Turret Level Also implemented the code for TractorBeamTurret thanks to the code changes Parallax can have the feature if needed for future balancing. Hopefully nothing was screwed up in the transition... * Counterbalance (1): Swarmer 8 -> 7 firerate nerf, and Cyclone 7.5 -> 6 firerate nerf [First Attempt] * Reload Turret Coolant Fixes (2): added a buffer if the excessReload exceeds more than 2 reloads. * Reload Turret Coolant Fixes (3): hotfix, the buffer actually works this time * turretDepositCooldown (5): Made the cooldown seperate from itemDepositCooldown * Implemented armorMultiplier (1) * fixing a merge * (AT:7a) Reverted Saving Capability * (AT:7b) Removed activation timer from lancer and arc as well as sprites * (AT:7c) Removed visuals for activation timer will be reimplemented via a greyscale effect if returned rather than via sprites * (AT:7aa) oops * Made the default value 0 when placed - Activation Timer (8) * (depositCooldown : 6) Moved depositCooldown to Blocks.java, cleaned up canDepositItem(), removed enableTurretDepositCooldown * armorMultiplier (2) - oops, made armorMultipler = 0 correspond to 100% armorPiercing * Update core/src/mindustry/input/InputHandler.java * Reload Turret Coolant Fixes (4): A bit too high --------- Co-authored-by: Anuken --- core/assets/bundles/bundle.properties | 6 +++ core/src/mindustry/content/Blocks.java | 16 ++++++- .../mindustry/entities/bullet/BulletType.java | 4 ++ .../mindustry/entities/comp/BuildingComp.java | 2 +- .../mindustry/entities/comp/HealthComp.java | 14 ++++++ .../mindustry/entities/comp/ShieldComp.java | 12 +++++ .../mindustry/graphics/OverlayRenderer.java | 2 +- core/src/mindustry/input/InputHandler.java | 11 ++++- core/src/mindustry/world/Block.java | 2 + .../blocks/defense/turrets/BaseTurret.java | 31 +++++++++++++ .../blocks/defense/turrets/ReloadTurret.java | 6 ++- .../defense/turrets/TractorBeamTurret.java | 5 +++ .../world/blocks/defense/turrets/Turret.java | 45 +++++++++++++++---- .../src/mindustry/world/meta/BlockStatus.java | 3 +- core/src/mindustry/world/meta/Stat.java | 1 + core/src/mindustry/world/meta/StatValues.java | 10 +++++ 16 files changed, 155 insertions(+), 15 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 8e4e733140..6cc516ca9a 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1073,6 +1073,7 @@ stat.ammo = Ammo stat.shieldhealth = Shield Health stat.cooldowntime = Cooldown Time stat.regenerationrate = Regeneration Rate +stat.activationtime = Activation Time stat.explosiveness = Explosiveness stat.basedeflectchance = Base Deflect Chance stat.lightningchance = Lightning Chance @@ -1183,6 +1184,8 @@ bar.input = Input bar.output = Output bar.strength = [stat]{0}[lightgray]x strength bar.regenerationrate = [stat]{0}/sec[lightgray] regen rate +bar.activationtimer = Activates in {0} +bar.activated = Activated units.processorcontrol = [lightgray]Processor Controlled @@ -1191,6 +1194,9 @@ bullet.splashdamage = [stat]{0}[lightgray] area dmg ~ [stat]{1}[lightgray] tiles bullet.incendiary = [stat]incendiary bullet.homing = [stat]homing bullet.armorpierce = [stat]armor piercing +bullet.armorweakness = [red]{0}%[lightgray] armor weakness +bullet.armorpiercing = [stat]{0}%[lightgray] armor piercing +bullet.antiarmor = [stat]{0}x[lightgray] anti-armor bullet.maxdamagefraction = [stat]{0}%[lightgray] damage limit bullet.suppression = [stat]{0}[lightgray] seconds of repair suppression ~ [stat]{1}[lightgray] tiles bullet.interval = [stat]{0}/sec[lightgray] interval bullets: diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 6fe2b66161..c23011525f 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -3322,6 +3322,7 @@ public class Blocks{ coolant = consumeCoolant(0.1f); coolantMultiplier = 10f; researchCostMultiplier = 0.05f; + depositCooldown = 2.0f; limitRange(5f); }}; @@ -3407,6 +3408,7 @@ public class Blocks{ shootSound = Sounds.shootScatter; coolant = consumeCoolant(0.2f); researchCostMultiplier = 0.05f; + depositCooldown = 0.5f; limitRange(2); }}; @@ -3453,6 +3455,7 @@ public class Blocks{ health = 400; shootSound = Sounds.shootFlame; coolant = consumeCoolant(0.1f); + depositCooldown = 1.0f; }}; hail = new ItemTurret("hail"){{ @@ -3517,6 +3520,7 @@ public class Blocks{ shootSound = Sounds.shootArtillerySmall; coolant = consumeCoolant(0.1f); coolantMultiplier = 10f; + depositCooldown = 2.0f; limitRange(0f); }}; @@ -3581,6 +3585,7 @@ public class Blocks{ chargeEffect = new MultiEffect(Fx.lancerLaserCharge, Fx.lancerLaserChargeBegin); buildingDamageMultiplier = 0.25f; + armorMultiplier = 4f; hitEffect = Fx.hitLancer; hitSize = 4; lifetime = 16f; @@ -3706,7 +3711,7 @@ public class Blocks{ }}; shootY = 4.5f; - reload = 30f; + reload = 60f * 4f / 7f; inaccuracy = 10f; range = 240f; consumeAmmoOnce = false; @@ -3717,6 +3722,7 @@ public class Blocks{ limitRange(5f); coolant = consumeCoolant(0.3f); + depositCooldown = 2.0f; }}; salvo = new ItemTurret("salvo"){{ @@ -3818,6 +3824,7 @@ public class Blocks{ limitRange(); coolant = consumeCoolant(0.2f); + depositCooldown = 2.0f; }}; segment = new PointDefenseTurret("segment"){{ @@ -3935,6 +3942,7 @@ public class Blocks{ shootEffect = smokeEffect = Fx.thoriumShoot; }} ); + depositCooldown = 1.0f; }}; ripple = new ItemTurret("ripple"){{ @@ -4063,6 +4071,7 @@ public class Blocks{ coolant = consumeCoolant(0.3f); scaledHealth = 130; + depositCooldown = 2.0f; shootSound = Sounds.shootRipple; }}; @@ -4168,7 +4177,7 @@ public class Blocks{ } }}; - reload = 8f; + reload = 10f; range = 200f; size = 3; recoil = 1.5f; @@ -4180,6 +4189,7 @@ public class Blocks{ coolant = consumeCoolant(0.3f); scaledHealth = 145; + depositCooldown = 2.0f; limitRange(); }}; @@ -4224,6 +4234,7 @@ public class Blocks{ scaledHealth = 150; coolant = consumeCoolant(1f); + depositCooldown = 2.0f; consumePower(10f); }}; @@ -4290,6 +4301,7 @@ public class Blocks{ scaledHealth = 160; coolant = consumeCoolant(1f); + depositCooldown = 2.0f; limitRange(); }}; diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index a74c13edce..9e2b10e846 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -181,6 +181,8 @@ public class BulletType extends Content implements Cloneable{ public boolean fragOnAbsorb = true; /** If true, unit armor is ignored in damage calculations. */ public boolean pierceArmor = false; + /** Multiplies the unit armor used in damage calculations. Used for armor weakness, armor piercing, and anti-armor. */ + public float armorMultiplier = 1f; /** If true, the bullet will "stick" to enemies and get deactivated on collision. */ public boolean sticky = false; /** Extra time added to bullet when it sticks to something. */ @@ -483,6 +485,8 @@ public class BulletType extends Content implements Cloneable{ } if(pierceArmor){ h.damagePierce(damage); + }else if(armorMultiplier != 1){ + h.damageArmorMult(damage, armorMultiplier); }else{ h.damage(damage); } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index baacb406ab..617a74fc96 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1727,7 +1727,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, float damage = other.type.buildingDamage(other); if(!other.type.pierceArmor){ - damage = Damage.applyArmor(damage, block.armor); + damage = Damage.applyArmor(damage, block.armor * other.type.armorMultiplier); } damage(other, other.team, damage); diff --git a/core/src/mindustry/entities/comp/HealthComp.java b/core/src/mindustry/entities/comp/HealthComp.java index f315b3fb75..cfc3cb92c4 100644 --- a/core/src/mindustry/entities/comp/HealthComp.java +++ b/core/src/mindustry/entities/comp/HealthComp.java @@ -58,6 +58,16 @@ abstract class HealthComp implements Entityc, Posc{ damagePierce(amount, true); } + /** Damage and multiply armor received. */ + void damageArmorMult(float amount, float armorMult, boolean withEffect){ + damage(amount, withEffect); + } + + /** Damage and multiply armor received. */ + void damageArmorMult(float amount, float armorMult){ + damageArmorMult(amount, armorMult, true); + } + void damage(float amount){ if(Float.isNaN(health)) health = 0f; @@ -86,6 +96,10 @@ abstract class HealthComp implements Entityc, Posc{ damagePierce(amount * Time.delta, hitTime <= -20 + hitDuration); } + void damageContinuousArmorMult(float amount, float armorMult){ + damageArmorMult(amount * Time.delta, armorMult, hitTime <= -20 + hitDuration); + } + void clampHealth(){ health = Math.min(health, maxHealth); if(Float.isNaN(health)) health = 0f; diff --git a/core/src/mindustry/entities/comp/ShieldComp.java b/core/src/mindustry/entities/comp/ShieldComp.java index f2f6e4c808..f67ece6f99 100644 --- a/core/src/mindustry/entities/comp/ShieldComp.java +++ b/core/src/mindustry/entities/comp/ShieldComp.java @@ -42,6 +42,18 @@ abstract class ShieldComp implements Healthc, Posc{ } } + @Replace + @Override + public void damageArmorMult(float amount, float armorMult, boolean withEffect){ + float pre = hitTime; + + rawDamage(Damage.applyArmor(amount, armorOverride >= 0f ? armorOverride * armorMult : armor * armorMult) / healthMultiplier / Vars.state.rules.unitHealth(team)); + + if(!withEffect){ + hitTime = pre; + } + } + protected void rawDamage(float amount){ boolean hadShields = shield > 0.0001f; diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index e9c3450503..78533c7fe7 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -248,7 +248,7 @@ public class OverlayRenderer{ Building build = world.buildWorld(v.x, v.y); if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange) && - input.itemDepositCooldown <= 0f){ + input.canDepositItem(build)){ boolean invalid = !build.allowDeposit(); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index c4263b7323..53245fb1f6 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -37,6 +37,7 @@ import mindustry.ui.fragments.*; import mindustry.world.*; import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.*; +import mindustry.world.blocks.defense.turrets.*; import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.storage.*; @@ -2154,7 +2155,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) && build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){ - if(build.allowDeposit() && itemDepositCooldown <= 0f){ + if(build.allowDeposit() && canDepositItem(build)){ Call.transferInventory(player, build); itemDepositCooldown = state.rules.itemDepositCooldown; } @@ -2163,6 +2164,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } + public boolean canDepositItem(Building build){ + //takes advantage of itemDepositCooldown being able to be negative, allows the cooldown to be different for each building + if(build.block.depositCooldown >= 0){ + return itemDepositCooldown - state.rules.itemDepositCooldown <= -build.block.depositCooldown; + } + return itemDepositCooldown <= 0; + } + public void rebuildArea(int x1, int y1, int x2, int y2){ NormalizeResult result = Placement.normalizeArea(x1, y1, x2, y2, rotation, false, 999999999); Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize); diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index e0658b5640..6cbed7004d 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -66,6 +66,8 @@ public class Block extends UnlockableContent implements Senseable{ public boolean acceptsItems = false; /** If true, this block won't be affected by the onlyDepositCore rule. */ public boolean alwaysAllowDeposit = false; + /** Cooldown, in seconds, applied to player item depositing when any item is deposited to this block. Overrides the itemDepositCooldown if non-negative. */ + public float depositCooldown = -1f; /** If true, all item capacities of this block are separate instead of pooled as one number. */ public boolean separateItemCapacity = false; /** maximum items this block can carry (usually, this is per-type of item) */ diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index b6c7510349..20ec8d43d9 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -1,5 +1,7 @@ package mindustry.world.blocks.defense.turrets; +import arc.*; +import arc.graphics.*; import arc.math.*; import arc.struct.*; import arc.util.*; @@ -8,6 +10,7 @@ import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.logic.*; +import mindustry.ui.*; import mindustry.world.*; import mindustry.world.blocks.*; import mindustry.world.consumers.*; @@ -21,6 +24,8 @@ public class BaseTurret extends Block{ public float rotateSpeed = 5; public float fogRadiusMultiplier = 1f; public boolean disableOverlapCheck = false; + /** How much time to start shooting after placement. */ + public float activationTime = 0f; /** Effect displayed when coolant is used. */ public Effect coolEffect = Fx.fuelburn; @@ -90,10 +95,31 @@ public class BaseTurret extends Block{ super.setStats(); stats.add(Stat.shootRange, range / tilesize, StatUnit.blocks); + if(activationTime > 0) stats.add(Stat.activationTime, activationTime / 60f, StatUnit.seconds); + } + + @Override + public void setBars(){ + super.setBars(); + + if(activationTime > 0){ + addBar("activationtimer", (BaseTurretBuild entity) -> + new Bar(() -> + (entity.activationTimer > 0)? Core.bundle.format("bar.activationtimer", Mathf.ceil(entity.activationTimer / 60f)) : Core.bundle.get("bar.activated"), + () -> (entity.activationTimer > 0)? Pal.lightOrange : Pal.techBlue, + () -> 1 - entity.activationTimer / activationTime)); + } } public class BaseTurretBuild extends Building implements Ranged, RotBlock{ public float rotation = 90; + public float activationTimer = 0; + + @Override + public void placed(){ + super.placed(); + activationTimer = activationTime; + } @Override public float range(){ @@ -113,5 +139,10 @@ public class BaseTurret extends Block{ public float estimateDps(){ return 0f; } + + @Override + public BlockStatus status() { + return (activationTimer <= 0)? super.status() : BlockStatus.inactive; + } } } diff --git a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java index 8748b91ed8..6b5721987b 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java @@ -26,7 +26,7 @@ public class ReloadTurret extends BaseTurret{ public float reloadCounter; protected void updateCooling(){ - if(reloadCounter < reload && coolant != null && coolant.efficiency(this) > 0 && efficiency > 0){ + if(canReload() && coolant != null && coolant.efficiency(this) > 0 && efficiency > 0){ float capacity = coolant instanceof ConsumeLiquidFilter filter ? filter.getConsumed(this).heatCapacity : (coolant.consumes(liquids.current()) ? liquids.current().heatCapacity : 0.4f); float amount = coolant.amount * coolant.efficiency(this); coolant.update(this); @@ -45,5 +45,9 @@ public class ReloadTurret extends BaseTurret{ protected float baseReloadSpeed(){ return efficiency; } + + protected boolean canReload(){ + return reloadCounter < reload; + } } } diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index aa447d6ae7..35a746dbc5 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -76,6 +76,11 @@ public class TractorBeamTurret extends BaseTurret{ @Override public void updateTile(){ + if(activationTimer > 0){ + activationTimer -= Time.delta; + return; + } + float eff = efficiency * coolantMultiplier, edelta = eff * delta(); //retarget diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 9f8e5edd4a..cb4a38ee8d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -278,6 +278,8 @@ public class Turret extends ReloadTurret{ public @Nullable float[] curRecoils; public float shootWarmup, charge, warmupHold = 0f; public int totalShots, barrelCounter; + public float excessReload = 0; + public int reloadShots = 0; public boolean logicShooting = false; public @Nullable Posc target; public Vec2 targetPos = new Vec2(); @@ -419,7 +421,7 @@ public class Turret extends ReloadTurret{ } public boolean isActive(){ - return (target != null || wasShooting) && enabled; + return (target != null || wasShooting) && enabled && activationTimer <= 0; } public void targetPosition(Posc pos){ @@ -481,8 +483,6 @@ public class Turret extends ReloadTurret{ shootWarmup = Mathf.lerpDelta(shootWarmup, warmupTarget, shootWarmupSpeed * (warmupTarget > 0 ? efficiency : 1f)); } - wasShooting = false; - curRecoil = Mathf.approachDelta(curRecoil, 0, 1 / recoilTime); if(recoils > 0){ if(curRecoils == null) curRecoils = new float[recoils]; @@ -515,8 +515,11 @@ public class Turret extends ReloadTurret{ if(reloadWhileCharging || !charging()){ updateReload(); updateCooling(); + capReload(); } + wasShooting = false; + if(state.rules.fog){ float newRange = hasAmmo() ? peekAmmo().rangeChange : 0f; if(newRange != lastRangeChange){ @@ -525,6 +528,11 @@ public class Turret extends ReloadTurret{ } } + if(activationTimer > 0){ + activationTimer -= Time.delta; + return; + } + if(hasAmmo()){ if(Float.isNaN(reloadCounter)) reloadCounter = 0; @@ -673,11 +681,30 @@ public class Turret extends ReloadTurret{ return queuedBullets > 0 && shoot.firstShotDelay > 0; } - protected void updateReload(){ - reloadCounter += delta() * ammoReloadMultiplier() * baseReloadSpeed(); + @Override + protected boolean canReload(){ + //keep reloading as the turret keeps shooting + return reloadShots < 1 || wasShooting; + } - //cap reload for visual reasons + protected void updateReload(){ + if(!canReload()) return; + reloadCounter += delta() * ammoReloadMultiplier() * baseReloadSpeed(); + } + + protected void capReload(){ + //cap reload for visual reasons, need to store the excess reload to keep the firerate consistent + if(canReload() && reloadCounter >= reload){ + reloadShots += (int)(reloadCounter / reload); + excessReload += reloadCounter % reload; + } reloadCounter = Math.min(reloadCounter, reload); + reloadShots = Math.min(reloadShots, 5); + + if(!wasShooting){ + reloadShots = 0; + excessReload = 0; + } } @Override @@ -687,12 +714,14 @@ public class Turret extends ReloadTurret{ protected void updateShooting(){ - if(reloadCounter >= reload && !charging() && shootWarmup >= minWarmup){ + if(reloadShots > 0 && !charging() && shootWarmup >= minWarmup){ BulletType type = peekAmmo(); shoot(type); - reloadCounter %= reload; + reloadCounter = excessReload; + excessReload = 0; + reloadShots--; } } diff --git a/core/src/mindustry/world/meta/BlockStatus.java b/core/src/mindustry/world/meta/BlockStatus.java index d21887244e..f22b3d5054 100644 --- a/core/src/mindustry/world/meta/BlockStatus.java +++ b/core/src/mindustry/world/meta/BlockStatus.java @@ -7,7 +7,8 @@ public enum BlockStatus{ active(Color.valueOf("5ce677")), noOutput(Color.orange), noInput(Pal.remove), - logicDisable(Color.valueOf("8a73c6")); + logicDisable(Color.valueOf("8a73c6")), + inactive(Color.lightGray); public final Color color; diff --git a/core/src/mindustry/world/meta/Stat.java b/core/src/mindustry/world/meta/Stat.java index 37974939ef..6dcef85afe 100644 --- a/core/src/mindustry/world/meta/Stat.java +++ b/core/src/mindustry/world/meta/Stat.java @@ -95,6 +95,7 @@ public class Stat implements Comparable{ shieldHealth = new Stat("shieldHealth", StatCat.function), cooldownTime = new Stat("cooldownTime", StatCat.function), regenerationRate = new Stat("regenerationRate", StatCat.function), + activationTime = new Stat("activationTime", StatCat.function), moduleTier = new Stat("moduletier", StatCat.function), unitType = new Stat("unittype", StatCat.function), diff --git a/core/src/mindustry/world/meta/StatValues.java b/core/src/mindustry/world/meta/StatValues.java index b2694d1c8f..8556ef3adc 100644 --- a/core/src/mindustry/world/meta/StatValues.java +++ b/core/src/mindustry/world/meta/StatValues.java @@ -704,6 +704,16 @@ public class StatValues{ sep(bt, "@bullet.armorpierce"); } + if(type.armorMultiplier != 1f){ + if(type.armorMultiplier > 1f){ + sep(bt, Core.bundle.format("bullet.armorweakness", (int)(type.armorMultiplier * 100))); + }else if(Mathf.sign(type.armorMultiplier) == 1){ + sep(bt, Core.bundle.format("bullet.armorpiercing", (int)((1 - type.armorMultiplier) * 100))); + }else{ + sep(bt, Core.bundle.format("bullet.antiarmor", (-type.armorMultiplier))); + } + } + if(type.maxDamageFraction > 0){ sep(bt, Core.bundle.format("bullet.maxdamagefraction", (int)(type.maxDamageFraction * 100))); }