From 8ede0fa6f4100f4dfdae04442ba814d84bc04d0d Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 15 Sep 2024 19:21:24 -0400 Subject: [PATCH] Fixed shields not blocking blast compound explosions --- core/src/mindustry/content/UnitTypes.java | 4 ++-- core/src/mindustry/entities/Damage.java | 14 ++++++++++---- core/src/mindustry/entities/comp/UnitComp.java | 2 +- core/src/mindustry/game/CampaignRules.java | 3 ++- .../mindustry/world/blocks/ExplosionShield.java | 7 +++++++ .../mindustry/world/blocks/UnitWreckShield.java | 9 --------- .../world/blocks/defense/ForceProjector.java | 10 +++++----- 7 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 core/src/mindustry/world/blocks/ExplosionShield.java delete mode 100644 core/src/mindustry/world/blocks/UnitWreckShield.java diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 729a245f8c..d50ea28261 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1042,7 +1042,7 @@ public class UnitTypes{ status = StatusEffects.blasted; statusDuration = 60f; - damage = splashDamage * 0.75f; + damage = splashDamage * 0.7f; }}; }}); }}; @@ -1447,7 +1447,7 @@ public class UnitTypes{ healPercent = 15f; splashDamage = 220f; splashDamageRadius = 80f; - damage = splashDamage * 0.75f; + damage = splashDamage * 0.7f; }}; }}); }}; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 988b92660e..7f13c16546 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -16,6 +16,8 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; import mindustry.world.*; +import mindustry.world.blocks.*; +import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -101,9 +103,13 @@ public class Damage{ float damagePerWave = explosiveness / 2f; for(int i = 0; i < waves; i++){ + var shields = ignoreTeam == null ? null : indexer.getEnemy(ignoreTeam, BlockFlag.shield); int f = i; Time.run(i * 2f, () -> { - damage(ignoreTeam, x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), damagePerWave, false); + if(shields == null || shields.isEmpty() || !shields.contains(b -> b instanceof ExplosionShield s && s.absorbExplosion(x, y, damagePerWave))){ + damage(ignoreTeam, x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), damagePerWave, false); + } + Fx.blockExplosionSmoke.at(x + Mathf.range(radius), y + Mathf.range(radius)); }); } @@ -166,7 +172,7 @@ public class Damage{ public static float findPierceLength(Bullet b, int pierceCap, float length){ return findPierceLength(b, pierceCap, b.type.laserAbsorb, length); } - + public static float findPierceLength(Bullet b, int pierceCap, boolean laser, float length){ vec.trnsExact(b.rotation(), length); rect.setPosition(b.x, b.y).setSize(vec.x, vec.y).normalize().grow(3f); @@ -358,7 +364,7 @@ public class Damage{ */ public static Healthc linecast(Bullet hitter, float x, float y, float angle, float length){ vec.trns(angle, length); - + tmpBuilding = null; if(hitter.type.collidesGround){ @@ -644,7 +650,7 @@ public class Damage{ this.target = target; return this; } - + @Override public void reset(){ target = null; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index f5cc151a2c..548e34965e 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -717,7 +717,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I if(type.flying && !spawnedByCore && type.createWreck && state.rules.unitCrashDamage(team) > 0){ var shields = indexer.getEnemy(team, BlockFlag.shield); float crashDamage = Mathf.pow(hitSize, 0.75f) * type.crashDamageMultiplier * 5f * state.rules.unitCrashDamage(team); - if(shields.isEmpty() || !shields.contains(b -> b instanceof UnitWreckShield s && s.absorbWreck(self(), crashDamage))){ + if(shields.isEmpty() || !shields.contains(b -> b instanceof ExplosionShield s && s.absorbExplosion(x, y, crashDamage))){ Damage.damage(team, x, y, Mathf.pow(hitSize, 0.94f) * 1.25f, crashDamage, true, false, true); } } diff --git a/core/src/mindustry/game/CampaignRules.java b/core/src/mindustry/game/CampaignRules.java index 052315f656..2865c7d12f 100644 --- a/core/src/mindustry/game/CampaignRules.java +++ b/core/src/mindustry/game/CampaignRules.java @@ -17,10 +17,11 @@ public class CampaignRules{ rules.showSpawns = showSpawns; rules.randomWaveAI = randomWaveAI; if(planet.showRtsAIRule && rules.attackMode){ + boolean swapped = rules.teams.get(rules.waveTeam).rtsAi != rtsAI; rules.teams.get(rules.waveTeam).rtsAi = rtsAI; rules.teams.get(rules.waveTeam).rtsMinWeight = 1.2f * difficulty.enemyHealthMultiplier; - if(Vars.state.isGame()){ + if(swapped && Vars.state.isGame()){ Groups.unit.each(u -> { if(u.team == rules.waveTeam && !u.isPlayer()){ u.resetController(); diff --git a/core/src/mindustry/world/blocks/ExplosionShield.java b/core/src/mindustry/world/blocks/ExplosionShield.java new file mode 100644 index 0000000000..892795632c --- /dev/null +++ b/core/src/mindustry/world/blocks/ExplosionShield.java @@ -0,0 +1,7 @@ +package mindustry.world.blocks; + +//TODO: horrible API design, but I'm not sure of a better way to do this right now. please don't use this class +public interface ExplosionShield{ + /** @return whether the shield was able to absorb the explosion; this should apply damage to the shield if true is returned. */ + boolean absorbExplosion(float x, float y, float damage); +} diff --git a/core/src/mindustry/world/blocks/UnitWreckShield.java b/core/src/mindustry/world/blocks/UnitWreckShield.java deleted file mode 100644 index 062320cef2..0000000000 --- a/core/src/mindustry/world/blocks/UnitWreckShield.java +++ /dev/null @@ -1,9 +0,0 @@ -package mindustry.world.blocks; - -import mindustry.gen.*; - -//TODO: horrible API design, but I'm not sure of a better way to do this right now. please don't use this class -public interface UnitWreckShield{ - /** @return whether the shield was able to absorb the unit wreck; this should apply damage to the shield if true is returned. */ - boolean absorbWreck(Unit unit, float damage); -} diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index a976773de7..f62e8fa12e 100644 --- a/core/src/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/ForceProjector.java @@ -40,7 +40,7 @@ public class ForceProjector extends Block{ public float cooldownBrokenBase = 0.35f; public float coolantConsumption = 0.1f; public boolean consumeCoolant = true; - public float crashDamageMultiplier = 2.5f; + public float crashDamageMultiplier = 2f; public Effect absorbEffect = Fx.absorb; public Effect shieldBreakEffect = Fx.shieldBreak; public @Load("@-top") TextureRegion topRegion; @@ -123,7 +123,7 @@ public class ForceProjector extends Block{ Draw.color(); } - public class ForceBuild extends Building implements Ranged, UnitWreckShield{ + public class ForceBuild extends Building implements Ranged, ExplosionShield{ public boolean broken = true; public float buildup, radscl, hit, warmup, phaseHeat; @@ -218,10 +218,10 @@ public class ForceProjector extends Block{ } @Override - public boolean absorbWreck(Unit unit, float damage){ - boolean absorb = !broken && Intersector.isInRegularPolygon(sides, x, y, realRadius(), shieldRotation, unit.x, unit.y); + public boolean absorbExplosion(float ex, float ey, float damage){ + boolean absorb = !broken && Intersector.isInRegularPolygon(sides, x, y, realRadius(), shieldRotation, ex, ey); if(absorb){ - absorbEffect.at(unit); + absorbEffect.at(ex, ey); hit = 1f; buildup += damage * crashDamageMultiplier; }