From 9911e602a0e8e366f7eb4f8a6d6a0d207c6e1da1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 15 Sep 2024 17:20:34 -0400 Subject: [PATCH] Quads+Horizons damage shields / RTS AI toggle for Serpulo --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/ai/RtsAI.java | 2 +- core/src/mindustry/content/Planets.java | 2 ++ core/src/mindustry/content/UnitTypes.java | 11 ++++++++--- core/src/mindustry/entities/Units.java | 2 +- core/src/mindustry/game/CampaignRules.java | 19 ++++++++++++++++++- core/src/mindustry/type/Planet.java | 17 ++++++++++------- .../ui/dialogs/CampaignRulesDialog.java | 5 ++++- .../world/blocks/defense/ForceProjector.java | 2 +- 9 files changed, 47 insertions(+), 15 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index bcd0ca3ce3..dbf74d3235 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1359,6 +1359,8 @@ rules.attack = Attack Mode rules.buildai = Base Builder AI rules.buildaitier = Builder AI Tier rules.rtsai = RTS AI [red](WIP) +rules.rtsai.campaign = RTS Attack AI +rules.rtsai.campaign.info = In attack maps, makes units group up and attack player bases in a more intelligent manner. rules.rtsminsquadsize = Min Squad Size rules.rtsmaxsquadsize = Max Squad Size rules.rtsminattackweight = Min Attack Weight diff --git a/core/src/mindustry/ai/RtsAI.java b/core/src/mindustry/ai/RtsAI.java index 16fcf3ec7a..b97e58e464 100644 --- a/core/src/mindustry/ai/RtsAI.java +++ b/core/src/mindustry/ai/RtsAI.java @@ -343,7 +343,7 @@ public class RtsAI{ //other can never be destroyed | other destroys self instantly if(Float.isInfinite(timeDestroyOther) || Mathf.zero(timeDestroySelf)) return 0f; //self can never be destroyed | self destroys other instantly - if(Float.isInfinite(timeDestroySelf) || Mathf.zero(timeDestroyOther)) return 1f; + if(Float.isInfinite(timeDestroySelf) || Mathf.zero(timeDestroyOther)) return 100000f; //examples: // self 10 sec / other 10 sec -> can destroy target with 100 % losses -> returns 1 diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java index a37488943c..1413b40a3a 100644 --- a/core/src/mindustry/content/Planets.java +++ b/core/src/mindustry/content/Planets.java @@ -87,6 +87,7 @@ public class Planets{ }; campaignRuleDefaults.fog = true; campaignRuleDefaults.showSpawns = true; + campaignRuleDefaults.rtsAI = true; unlockedOnLand.add(Blocks.coreBastion); }}; @@ -146,6 +147,7 @@ public class Planets{ r.placeRangeCheck = false; r.showSpawns = false; }; + showRtsAIRule = true; iconColor = Color.valueOf("7d4dff"); atmosphereColor = Color.valueOf("3c1b8f"); atmosphereRadIn = 0.02f; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 4c7e9def50..729a245f8c 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1042,6 +1042,7 @@ public class UnitTypes{ status = StatusEffects.blasted; statusDuration = 60f; + damage = splashDamage * 0.75f; }}; }}); }}; @@ -1446,6 +1447,7 @@ public class UnitTypes{ healPercent = 15f; splashDamage = 220f; splashDamageRadius = 80f; + damage = splashDamage * 0.75f; }}; }}); }}; @@ -2364,7 +2366,8 @@ public class UnitTypes{ //region core alpha = new UnitType("alpha"){{ - aiController = BuilderAI::new; + aiController = () -> new BuilderAI(true, 400f); + controller = u -> u.team.isAI() ? aiController.get() : new CommandAI(); isEnemy = false; lowAltitude = true; @@ -2402,7 +2405,8 @@ public class UnitTypes{ }}; beta = new UnitType("beta"){{ - aiController = BuilderAI::new; + aiController = () -> new BuilderAI(true, 400f); + controller = u -> u.team.isAI() ? aiController.get() : new CommandAI(); isEnemy = false; flying = true; @@ -2443,7 +2447,8 @@ public class UnitTypes{ }}; gamma = new UnitType("gamma"){{ - aiController = BuilderAI::new; + aiController = () -> new BuilderAI(true, 400f); + controller = u -> u.team.isAI() ? aiController.get() : new CommandAI(); isEnemy = false; lowAltitude = true; diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index c0f02cb196..5cdf7547b5 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -475,7 +475,7 @@ public class Units{ Seq data = state.teams.present; for(int i = 0; i < data.size; i++){ var other = data.items[i]; - if(other.team != team){ + if(other.team != team && other.team != Team.derelict){ if(other.tree().any(x, y, width, height)){ return true; } diff --git a/core/src/mindustry/game/CampaignRules.java b/core/src/mindustry/game/CampaignRules.java index 13e3389d43..052315f656 100644 --- a/core/src/mindustry/game/CampaignRules.java +++ b/core/src/mindustry/game/CampaignRules.java @@ -1,16 +1,33 @@ package mindustry.game; +import mindustry.*; +import mindustry.gen.*; +import mindustry.type.*; + public class CampaignRules{ public Difficulty difficulty = Difficulty.normal; public boolean fog; public boolean showSpawns; public boolean sectorInvasion; public boolean randomWaveAI; + public boolean rtsAI; - public void apply(Rules rules){ + public void apply(Planet planet, Rules rules){ rules.staticFog = rules.fog = fog; rules.showSpawns = showSpawns; rules.randomWaveAI = randomWaveAI; + if(planet.showRtsAIRule && rules.attackMode){ + rules.teams.get(rules.waveTeam).rtsAi = rtsAI; + rules.teams.get(rules.waveTeam).rtsMinWeight = 1.2f * difficulty.enemyHealthMultiplier; + + if(Vars.state.isGame()){ + Groups.unit.each(u -> { + if(u.team == rules.waveTeam && !u.isPlayer()){ + u.resetController(); + } + }); + } + } rules.teams.get(rules.waveTeam).blockHealthMultiplier = difficulty.enemyHealthMultiplier; rules.teams.get(rules.waveTeam).unitHealthMultiplier = difficulty.enemyHealthMultiplier; rules.teams.get(rules.waveTeam).unitCostMultiplier = 1f / difficulty.enemySpawnMultiplier; diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index 23cc55efec..41344793f3 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -136,12 +136,6 @@ public class Planet extends UnlockableContent{ public Music launchMusic = Musics.launch; /** Default core block for launching. */ public Block defaultCore = Blocks.coreShard; - /** Global difficulty/modifier settings for this planet's campaign. */ - public CampaignRules campaignRules = new CampaignRules(); - /** Defaults applied to the rules. */ - public CampaignRules campaignRuleDefaults = new CampaignRules(); - /** Sets up rules on game load for any sector on this planet. */ - public Cons ruleSetter = r -> {}; /** Parent body that this planet orbits around. If null, this planet is considered to be in the middle of the solar system. */ public @Nullable Planet parent; /** The root parent of the whole solar system this planet is in. */ @@ -161,6 +155,15 @@ public class Planet extends UnlockableContent{ /** Loads the planet grid outline mesh. Clientside only. */ public Prov gridMeshLoader = () -> MeshBuilder.buildPlanetGrid(grid, outlineColor, outlineRad * radius); + /** Global difficulty/modifier settings for this planet's campaign. */ + public CampaignRules campaignRules = new CampaignRules(); + /** Defaults applied to the rules. */ + public CampaignRules campaignRuleDefaults = new CampaignRules(); + /** Sets up rules on game load for any sector on this planet. */ + public Cons ruleSetter = r -> {}; + /** If true, RTS AI can be customized. */ + public boolean showRtsAIRule = false; + /** @deprecated no-op, do not use. */ @Deprecated public Seq itemWhitelist = new Seq<>(), hiddenItems = new Seq<>(); @@ -233,7 +236,7 @@ public class Planet extends UnlockableContent{ rules.planet = this; if(!customGame){ - campaignRules.apply(rules); + campaignRules.apply(this, rules); } } diff --git a/core/src/mindustry/ui/dialogs/CampaignRulesDialog.java b/core/src/mindustry/ui/dialogs/CampaignRulesDialog.java index c528bbcaae..317d321287 100644 --- a/core/src/mindustry/ui/dialogs/CampaignRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CampaignRulesDialog.java @@ -24,7 +24,7 @@ public class CampaignRulesDialog extends BaseDialog{ planet.saveRules(); if(Vars.state.isGame() && Vars.state.isCampaign() && Vars.state.getPlanet() == planet){ - planet.campaignRules.apply(Vars.state.rules); + planet.campaignRules.apply(planet, Vars.state.rules); Call.setRules(Vars.state.rules); } } @@ -60,6 +60,9 @@ public class CampaignRulesDialog extends BaseDialog{ check("@rules.fog", b -> rules.fog = b, () -> rules.fog); check("@rules.showspawns", b -> rules.showSpawns = b, () -> rules.showSpawns); check("@rules.randomwaveai", b -> rules.randomWaveAI = b, () -> rules.randomWaveAI); + if(planet.showRtsAIRule){ + check("@rules.rtsai.campaign", b -> rules.rtsAI = b, () -> rules.rtsAI); + } }).growY(); } diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index 5798bd9848..a976773de7 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 = 2f; + public float crashDamageMultiplier = 2.5f; public Effect absorbEffect = Fx.absorb; public Effect shieldBreakEffect = Fx.shieldBreak; public @Load("@-top") TextureRegion topRegion;