diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index fdbfb5e26d..d9cfd2bb5c 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -832,6 +832,7 @@ public class Blocks{ size = 2; hasPower = true; drawer = new DrawWeave(); + envEnabled |= Env.space; ambientSound = Sounds.techloop; ambientSoundVolume = 0.02f; @@ -994,6 +995,7 @@ public class Blocks{ incinerator = new Incinerator("incinerator"){{ requirements(Category.crafting, with(Items.graphite, 5, Items.lead, 15)); health = 90; + envEnabled |= Env.space; consumes.power(0.50f); }}; @@ -2146,6 +2148,8 @@ public class Blocks{ tier = 2; drillTime = 600; size = 2; + //mechanical drill doesn't work in space + envEnabled ^= Env.space; consumes.liquid(Liquids.water, 0.05f).boost(); }}; @@ -2167,7 +2171,6 @@ public class Blocks{ tier = 4; updateEffect = Fx.pulverizeMedium; drillEffect = Fx.mineBig; - envEnabled |= Env.space; consumes.power(1.10f); consumes.liquid(Liquids.water, 0.08f).boost(); @@ -2570,6 +2573,7 @@ public class Blocks{ flags = EnumSet.of(BlockFlag.turret, BlockFlag.extinguisher); }}; + //TODO these may work in space, but what's the point? lancer = new PowerTurret("lancer"){{ requirements(Category.turret, with(Items.copper, 60, Items.lead, 70, Items.silicon, 50)); range = 165f; @@ -2656,6 +2660,7 @@ public class Blocks{ size = 2; scaledHealth = 300; shootSound = Sounds.missile; + envEnabled |= Env.space; limitRange(5f); }}; @@ -2699,6 +2704,7 @@ public class Blocks{ shootLength = 5f; bulletDamage = 30f; reloadTime = 8f; + envEnabled |= Env.space; }}; tsunami = new LiquidTurret("tsunami"){{ @@ -2736,6 +2742,7 @@ public class Blocks{ restitution = 0.1f; shootCone = 30; size = 3; + envEnabled |= Env.space; scaledHealth = 220; shootSound = Sounds.shotgun; @@ -2846,6 +2853,7 @@ public class Blocks{ shootCone = 2f; shootSound = Sounds.railgun; unitSort = UnitSorts.strongest; + envEnabled |= Env.space; coolantMultiplier = 0.4f; @@ -2898,6 +2906,7 @@ public class Blocks{ shootSound = Sounds.laserbig; loopSound = Sounds.beam; loopSoundVolume = 2f; + envEnabled |= Env.space; shootType = new ContinuousLaserBulletType(78){{ length = 200f; diff --git a/core/src/mindustry/content/Loadouts.java b/core/src/mindustry/content/Loadouts.java index 1e3a17680b..70be4eb4a8 100644 --- a/core/src/mindustry/content/Loadouts.java +++ b/core/src/mindustry/content/Loadouts.java @@ -1,6 +1,5 @@ package mindustry.content; -import mindustry.ctype.*; import mindustry.game.*; public class Loadouts{ @@ -8,6 +7,7 @@ public class Loadouts{ basicShard, basicFoundation, basicNucleus, + spaceNucleus, basicBastion; public static void load(){ @@ -15,5 +15,6 @@ public class Loadouts{ basicFoundation = Schematics.readBase64("bXNjaAB4nD1OSQ6DMBBzFhVu8BG+0X8MQyoiJTNSukj8nlCi2Adbtg/GA4OBF8oB00rvyE/9ykafqOIw58A7SWRKy1ZiShhZ5RcOLZhYS1hefQ1gRIeptH9jq/qW2lvc1d2tgWsOfVX/tOwE86AYBA=="); basicNucleus = Schematics.readBase64("bXNjaAB4nD2MUQqAIBBEJy0s6qOLdJXuYNtCgikYBd2+LNmdj308hkGHtkId7M4YFns4mk/yfB4a48602eDI+mlNznu0FMPFd0wYKCaewl8F0EOueqM+yKSLVfJrNKWnSw/FZGzEGXFG9sy/px4gEBW1"); basicBastion = Schematics.readBase64("bXNjaAF4nGNgYWBhZmDJS8xNZWBNzMsEUtwpqcXJRZkFJZn5eQyClfmlCin5Cnn5JQqpFZnFJVwMbDmJSak5xQxM0bGMDDzJ+UWpukmJxWDVDAyMIAQkACMdFqE="); + spaceNucleus = Schematics.readBase64("bXNjaAF4nDXKuwrCQBRF0WMStVDwQyQJAStBrCxEKxsLsZjcXJiBeTEPB/9eQdzlYmOOZY3GCsPYypR83Pd9KaV7u5zyyB050xeRSB5fh+F2ulz9neTujNXEkYLySTkLYKHFyDqiejwrbLzlbERS1E5BaY01ucCtzaQ5x+9d49cMFRr84QNbTSRJ"); } } diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 9fd2f0d247..6c0b95ff53 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -183,42 +183,53 @@ public class SectorDamage{ if(core == null || spawns.isEmpty()) return; + boolean airOnly = !state.rules.spawns.contains(g -> !g.type.flying); + Tile start = spawns.first(); - - var field = pathfinder.getField(state.rules.waveTeam, Pathfinder.costGround, Pathfinder.fieldCore); Seq path = new Seq<>(); - boolean found = false; - if(field != null && field.weights != null){ - int[][] weights = field.weights; - int count = 0; - Tile current = start; - while(count < world.width() * world.height()){ - int minCost = Integer.MAX_VALUE; - int cx = current.x, cy = current.y; - for(Point2 p : Geometry.d4){ - int nx = cx + p.x, ny = cy + p.y; + //TODO would be nice if this worked in a more generic way, with two different calculations and paths + if(airOnly){ + world.raycastEach(start.x, start.y, core.tileX(), core.tileY(), (x, y) -> { + path.add(world.rawTile(x, y)); + return false; + }); + }else{ + var field = pathfinder.getField(state.rules.waveTeam, Pathfinder.costGround, Pathfinder.fieldCore); + boolean found = false; - Tile other = world.tile(nx, ny); - if(other != null && weights[nx][ny] < minCost && weights[nx][ny] != -1){ - minCost = weights[nx][ny]; - current = other; + if(field != null && field.weights != null){ + int[][] weights = field.weights; + int count = 0; + Tile current = start; + while(count < world.width() * world.height()){ + int minCost = Integer.MAX_VALUE; + int cx = current.x, cy = current.y; + for(Point2 p : Geometry.d4){ + int nx = cx + p.x, ny = cy + p.y; + + Tile other = world.tile(nx, ny); + if(other != null && weights[nx][ny] < minCost && weights[nx][ny] != -1){ + minCost = weights[nx][ny]; + current = other; + } } + + path.add(current); + + if(current.build == core){ + found = true; + break; + } + + count ++; } - - path.add(current); - - if(current.build == core){ - found = true; - break; - } - - count ++; } - } - if(!found){ - path = Astar.pathfind(start, core.tile, SectorDamage::cost, t -> !(t.block().isStatic() && t.solid())); + if(!found){ + path.clear(); + path.addAll(Astar.pathfind(start, core.tile, SectorDamage::cost, t -> !(t.block().isStatic() && t.solid()))); + } } //create sparse tile array for fast range query diff --git a/core/src/mindustry/maps/planet/AsteroidGenerator.java b/core/src/mindustry/maps/planet/AsteroidGenerator.java index 279b3835b8..3c1b7b5866 100644 --- a/core/src/mindustry/maps/planet/AsteroidGenerator.java +++ b/core/src/mindustry/maps/planet/AsteroidGenerator.java @@ -118,8 +118,8 @@ public class AsteroidGenerator extends BlankPlanetGenerator{ wallOre(Blocks.beryllicStoneWall, Blocks.wallOreBeryl, 50f, 0.62f * berylliumScale); //TODO: - //- copper maybe should not exist - //- consider replacing certain ores with something else + //- enemy wave spawns + //- never ending //titanium pass((x, y) -> { @@ -131,6 +131,10 @@ public class AsteroidGenerator extends BlankPlanetGenerator{ } }); + int spawnSide = rand.random(3); + int sizeOffset = width / 2 - 1; + tiles.getn(sizeOffset * Geometry.d8edge[spawnSide].x + width/2, sizeOffset * Geometry.d8edge[spawnSide].y + height/2).setOverlay(Blocks.spawn); + Schematics.placeLaunchLoadout(sx, sy); state.rules.planetBackground = new PlanetParams(){{ @@ -139,9 +143,19 @@ public class AsteroidGenerator extends BlankPlanetGenerator{ camPos = new Vec3(1.2388899f, 1.6047299f, 2.4758825f); }}; //state.rules.backgroundTexture = "sprites/space.png"; - state.rules.dragMultiplier = 0.7f; //yes, yes space has 0 drag but 0% drag is very annoying + state.rules.dragMultiplier = 0.7f; //yes, space actually has 0 drag but true 0% drag is very annoying state.rules.borderDarkness = false; state.rules.environment = Env.space; + state.rules.waves = true; + //TODO maybe make this on by default everywhere + state.rules.showSpawns = true; + //TODO better wavegen, do it by hand even + state.rules.spawns = Waves.generate(0.5f, rand, false, true, false); + } + + @Override + public Schematic getDefaultLoadout(){ + return Loadouts.spaceNucleus; } @Override diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index e2db4e670c..0354fd86e1 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -679,7 +679,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ state.camPos.set(0f, camLength, 0.1f); if(Mathf.equal(state.otherCamAlpha, 1f, 0.01f)){ - //cam.position.set(params.otherCamPos).lerp(params.planet.position, params.otherCamAlpha).add(params.camPos); + //TODO change zoom too state.camPos.set(Tmp.v31.set(state.otherCamPos).lerp(state.planet.position, state.otherCamAlpha).add(state.camPos).sub(state.planet.position)); state.otherCamPos = null; @@ -1031,29 +1031,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ stable.pack(); stable.setPosition(x, y, Align.center); - //do not fade out for now, TODO remove? - /* - stable.update(() -> { - if(selected != null){ - if(launching){ - stable.color.sub(0, 0, 0, 0.05f * Time.delta); - }else{ - if(!state.planet.hasGrid()){ - stable.color.a = 1f; - }else{ - //fade out UI when not facing selected sector - Tmp.v31.set(selected.tile.v).rotate(Vec3.Y, -state.planet.getRotation()).scl(-1f).nor(); - float dot = planets.cam.direction.dot(Tmp.v31); - stable.color.a = Math.max(dot, 0f)*2f; - if(dot*2f <= -0.1f){ - selected = null; - updateSelected(); - } - } - } - } - });*/ - stable.act(0f); } @@ -1087,12 +1064,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ if(mode == look && !sector.hasBase()){ shouldHide = false; Sector from = findLauncher(sector); - if(from == null || mode == planetLaunch){ - //TODO use the standard nucleus core schematic. - if(mode == planetLaunch){ - listener.get(sector); - } - + if(from == null){ //clear loadout information, so only the basic loadout gets used universe.clearLoadoutInfo(); //free launch. @@ -1136,7 +1108,14 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ } }else if(mode == select){ listener.get(sector); + }else if(mode == planetLaunch){ //TODO make sure it doesn't have a base already. + + //TODO animation + //schematic selection and cost handled by listener + listener.get(sector); + control.playSector(sector); }else{ + //sector should have base here control.playSector(sector); } diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index 9d44bf4991..d4049b2e35 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -20,6 +20,7 @@ import static mindustry.Vars.*; public class Accelerator extends Block{ public @Load("launch-arrow") TextureRegion arrowRegion; + //TODO dynamic public Block launching = Blocks.coreNucleus; public int[] capacities = {}; @@ -111,7 +112,12 @@ public class Accelerator extends Block{ ui.planet.showPlanetLaunch(state.rules.sector, sector -> { //TODO cutscene, etc... + + //TODO should consume resources based on destination schem consume(); + + universe.clearLoadoutInfo(); + universe.updateLoadout(sector.planet.generator.getDefaultLoadout().findCore(), sector.planet.generator.getDefaultLoadout()); }); Events.fire(Trigger.acceleratorUse); diff --git a/core/src/mindustry/world/blocks/defense/turrets/PowerTurret.java b/core/src/mindustry/world/blocks/defense/turrets/PowerTurret.java index e3956cf2fc..50f44ab435 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/PowerTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/PowerTurret.java @@ -12,7 +12,6 @@ public class PowerTurret extends Turret{ public PowerTurret(String name){ super(name); hasPower = true; - envEnabled |= Env.space; } @Override diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index 1aae664e82..1624cbd611 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -73,6 +73,8 @@ public class Drill extends Block{ hasItems = true; ambientSound = Sounds.drill; ambientSoundVolume = 0.018f; + //drills work in space I guess + envEnabled |= Env.space; } @Override