diff --git a/core/assets/maps/windsweptIslands.msav b/core/assets/maps/windsweptIslands.msav index d5e838b60d..2c8547f6f9 100644 Binary files a/core/assets/maps/windsweptIslands.msav and b/core/assets/maps/windsweptIslands.msav differ diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index ec720f1570..0e321e1ed6 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -88,7 +88,7 @@ public class Vars implements Loadable{ /** duration of time between turns in ticks */ public static final float turnDuration = 2 * Time.toMinutes; /** chance of an invasion per turn, 1 = 100% */ - public static final float baseInvasionChance = 1f / 55f; + public static final float baseInvasionChance = 1f / 60f; /** how many turns have to pass before invasions start */ public static final int invasionGracePeriod = 20; /** min armor fraction damage; e.g. 0.05 = at least 5% damage */ diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 41dd134682..bf0f73c730 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -484,6 +484,7 @@ public class TechTree implements ContentList{ new Research(bryde), new Research(spectre), new Research(launchPad), + new Research(massDriver), new Research(impactReactor), new Research(additiveReconstructor), new Research(exponentialReconstructor) diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 3a3d3041f4..023eeb5631 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1413,12 +1413,12 @@ public class UnitTypes implements ContentList{ ejectEffect = Fx.casing1; shootSound = Sounds.missile; bullet = new MissileBulletType(2.7f, 12, "missile"){{ + keepVelocity = true; width = 8f; height = 8f; shrinkY = 0f; drag = -0.003f; homingRange = 60f; - keepVelocity = false; splashDamageRadius = 25f; splashDamage = 10f; lifetime = 80f; diff --git a/core/src/mindustry/game/Waves.java b/core/src/mindustry/game/Waves.java index 21adaac37c..28f742a3cd 100644 --- a/core/src/mindustry/game/Waves.java +++ b/core/src/mindustry/game/Waves.java @@ -277,7 +277,7 @@ public class Waves{ int cap = 150; float shieldStart = 30, shieldsPerWave = 20 + difficulty*30f; - float[] scaling = {1, 1.2f, 1.5f, 3f, 4f}; + float[] scaling = {1, 1.2f, 2f, 3f, 4f}; Intc createProgression = start -> { //main sequence diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 993d49d72f..045a0bd75b 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -111,23 +111,26 @@ public class SectorDamage{ float damage = getDamage(state.rules.sector.info); //scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier) - float scaled = Mathf.pow(damage, 1.6f); + float scaled = Mathf.pow(damage, 1.2f); - //apply damage to units - float unitDamage = damage * state.rules.sector.info.sumHealth; Tile spawn = spawner.getFirstSpawn(); //damage only units near the spawn point if(spawn != null){ Seq allies = new Seq<>(); + float sumUnitHealth = 0f; for(Unit ally : Groups.unit){ if(ally.team == state.rules.defaultTeam && ally.within(spawn, state.rules.dropZoneRadius * 2.5f)){ allies.add(ally); + sumUnitHealth += ally.health; } } allies.sort(u -> u.dst2(spawn)); + //apply damage to units + float unitDamage = damage * sumUnitHealth; + //damage units one by one, not uniformly for(var u : allies){ if(u.health < unitDamage){ @@ -335,9 +338,9 @@ public class SectorDamage{ info.waveDpsSlope = reg.slope; //enemy units like to aim for a lot of non-essential things, so increase resulting health slightly - info.sumHealth = sumHealth * 1.18f; + info.sumHealth = sumHealth * 1.2f; //players tend to have longer range units/turrets, so assume DPS is higher - info.sumDps = sumDps * 1.18f; + info.sumDps = sumDps * 1.2f; info.sumRps = sumRps; info.wavesSurvived = getWavesSurvived(info); @@ -348,13 +351,12 @@ public class SectorDamage{ Queue frontier = new Queue<>(); float[][] values = new float[tiles.width][tiles.height]; - float damage = fraction*80; //arbitrary damage value //phase one: find all spawnpoints for(Tile tile : tiles){ if((tile.block() instanceof CoreBlock && tile.team() == state.rules.waveTeam) || tile.overlay() == Blocks.spawn){ frontier.add(tile); - values[tile.x][tile.y] = damage; + values[tile.x][tile.y] = fraction * 80; } } @@ -368,14 +370,16 @@ public class SectorDamage{ int radius = 3; //only penetrate a certain % by health, not by distance - float totalHealth = damage >= 1f ? 1f : path.sumf(t -> { + float totalHealth = fraction >= 1f ? 1f : path.sumf(t -> { float s = 0; for(int dx = -radius; dx <= radius; dx++){ for(int dy = -radius; dy <= radius; dy++){ int wx = dx + t.x, wy = dy + t.y; if(wx >= 0 && wy >= 0 && wx < world.width() && wy < world.height() && Mathf.within(dx, dy, radius)){ Tile other = world.rawTile(wx, wy); - s += other.team() == state.rules.defaultTeam ? other.build.health / other.block().size : 0f; + if(!(other.block() instanceof CoreBlock)){ + s += other.team() == state.rules.defaultTeam ? other.build.health / other.block().size : 0f; + } } } } @@ -385,7 +389,7 @@ public class SectorDamage{ float healthCount = 0; out: - for(int i = 0; i < path.size && (healthCount < targetHealth || damage >= 1f); i++){ + for(int i = 0; i < path.size && (healthCount < targetHealth || fraction >= 1f); i++){ Tile t = path.get(i); for(int dx = -radius; dx <= radius; dx++){ @@ -405,7 +409,7 @@ public class SectorDamage{ removal.add(other.build); - if(healthCount >= targetHealth && damage < 0.999f){ + if(healthCount >= targetHealth && fraction < 0.999f){ break out; } } @@ -430,10 +434,10 @@ public class SectorDamage{ } } - float falloff = (damage) / (Math.max(tiles.width, tiles.height) * Mathf.sqrt2); + float falloff = (fraction) / (Math.max(tiles.width, tiles.height) * Mathf.sqrt2); int peak = 0; - if(damage > 0.1f){ + if(fraction > 0.1f){ //phase two: propagate the damage while(!frontier.isEmpty()){ peak = Math.max(peak, frontier.size);