diff --git a/core/assets/maps/seaPort.msav b/core/assets/maps/seaPort.msav new file mode 100644 index 0000000000..e2fbf6d090 Binary files /dev/null and b/core/assets/maps/seaPort.msav differ diff --git a/core/assets/maps/weatheredChannels.msav b/core/assets/maps/weatheredChannels.msav new file mode 100644 index 0000000000..f9ef2030e1 Binary files /dev/null and b/core/assets/maps/weatheredChannels.msav differ diff --git a/core/src/mindustry/content/SectorPresets.java b/core/src/mindustry/content/SectorPresets.java index 9ca699ba02..d9e0cb20ad 100644 --- a/core/src/mindustry/content/SectorPresets.java +++ b/core/src/mindustry/content/SectorPresets.java @@ -10,7 +10,7 @@ public class SectorPresets{ craters, biomassFacility, taintedWoods, frozenForest, ruinousShores, facility32m, windsweptIslands, stainedMountains, tarFields, frontier, fungalPass, infestedCanyons, atolls, mycelialBastion, extractionOutpost, saltFlats, testingGrounds, overgrowth, //polarAerodrome, impact0078, desolateRift, nuclearComplex, planetaryTerminal, - coastline, navalFortress, + coastline, navalFortress, weatheredChannels, seaPort, onset, aegis, lake, intersect, basin, atlas, split, marsh, peaks, ravine, caldera, stronghold, crevice, siege, crossroads, karst, origin; @@ -62,6 +62,10 @@ public class SectorPresets{ difficulty = 3; }}; + seaPort = new SectorPreset("seaPort", serpulo, 47){{ + difficulty = 4; + }}; + facility32m = new SectorPreset("facility32m", serpulo, 64){{ captureWave = 25; difficulty = 4; @@ -91,6 +95,11 @@ public class SectorPresets{ difficulty = 5; }}; + weatheredChannels = new SectorPreset("weatheredChannels", serpulo, 39){{ + captureWave = 40; + difficulty = 7; + }}; + navalFortress = new SectorPreset("navalFortress", serpulo, 216){{ difficulty = 9; }}; diff --git a/core/src/mindustry/content/SerpuloTechTree.java b/core/src/mindustry/content/SerpuloTechTree.java index d16d2908e7..25a63a52cd 100644 --- a/core/src/mindustry/content/SerpuloTechTree.java +++ b/core/src/mindustry/content/SerpuloTechTree.java @@ -464,6 +464,18 @@ public class SerpuloTechTree{ new Research(kiln), new Research(mechanicalPump) ), () -> { + node(seaPort, Seq.with( + new SectorComplete(biomassFacility), + new Research(navalFactory), + new Research(risso), + new Research(retusa), + new Research(steamGenerator), + new Research(cultivator), + new Research(coalCentrifuge) + ), () -> { + + }); + node(windsweptIslands, Seq.with( new SectorComplete(ruinousShores), new Research(pneumaticDrill), @@ -565,6 +577,12 @@ public class SerpuloTechTree{ new Research(navalFactory), new Research(payloadConveyor) ), () -> { + node(weatheredChannels, Seq.with( + new SectorComplete(impact0078) + ), () -> { + + }); + node(navalFortress, Seq.with( new SectorComplete(coastline), new SectorComplete(extractionOutpost), diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index 794edf5d04..4544d055a0 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -146,6 +146,13 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ if(hasAll){ Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation); + + if(current.block.instantBuild){ + if(plans.size > 0){ + plans.removeFirst(); + } + continue; + } }else{ current.stuck = true; } diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 9d4dc589c4..19d0c1d422 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -146,10 +146,22 @@ public class PlacementFragment{ } } - if(tryRecipe != null && tryRecipe.isVisible() && unlocked(tryRecipe)){ + if(tryRecipe == null && state.rules.editor){ + var tile = world.tileWorld(Core.input.mouseWorldX(), Core.input.mouseWorldY()); + if(tile != null){ + tryRecipe = + tile.block() != Blocks.air ? tile.block() : + tile.overlay() != Blocks.air ? tile.overlay() : + tile.floor() != Blocks.air ? tile.floor() : null; + } + } + + if(tryRecipe != null && ((tryRecipe.isVisible() && unlocked(tryRecipe)) || state.rules.editor)){ input.block = tryRecipe; tryRecipe.lastConfig = tryConfig; - currentCategory = input.block.category; + if(tryRecipe.isVisible()){ + currentCategory = input.block.category; + } return true; } } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 3bd6c3977c..7b83ab0ae2 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -328,6 +328,8 @@ public class Block extends UnlockableContent implements Senseable{ public boolean instantDeconstruct = false; /** If true, this block constructs immediately. This implies no resource requirement, and ignores configs - do not use, this is for performance only! */ public boolean instantBuild = false; + /** If true, this block can be placed even in "dark" areas. Only used for editor static walls. */ + public boolean ignoreBuildDarkness = false; /** Effect for placing the block. Passes size as rotation. */ public Effect placeEffect = Fx.placeBlock; /** Effect for breaking the block. Passes size as rotation. */ diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index a47363df2f..6288a0d235 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -165,7 +165,7 @@ public class Build{ /** Returns whether a tile can be placed at this location by this team. */ public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible){ //the wave team can build whatever they want as long as it's visible - banned blocks are not applicable - if(type == null || (checkVisible && (!type.environmentBuildable() || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible()))))){ + if(type == null || (!state.rules.editor && (checkVisible && (!type.environmentBuildable() || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible())))))){ return false; } @@ -205,7 +205,7 @@ public class Build{ } //campaign darkness check - if(world.getDarkness(x, y) >= 3){ + if(!type.ignoreBuildDarkness && world.getDarkness(x, y) >= 3){ return false; } diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java index dfd29de65b..2ea499d015 100644 --- a/core/src/mindustry/world/blocks/environment/Floor.java +++ b/core/src/mindustry/world/blocks/environment/Floor.java @@ -92,6 +92,7 @@ public class Floor extends Block{ placeableLiquid = true; allowRectanglePlacement = true; instantBuild = true; + ignoreBuildDarkness = true; placeEffect = Fx.rotateBlock; } diff --git a/core/src/mindustry/world/blocks/environment/StaticWall.java b/core/src/mindustry/world/blocks/environment/StaticWall.java index 56fc569b24..49bfdd9a31 100644 --- a/core/src/mindustry/world/blocks/environment/StaticWall.java +++ b/core/src/mindustry/world/blocks/environment/StaticWall.java @@ -5,6 +5,7 @@ import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; import mindustry.graphics.*; import mindustry.world.*; @@ -21,7 +22,10 @@ public class StaticWall extends Prop{ variants = 2; cacheLayer = CacheLayer.walls; allowRectanglePlacement = true; + placeEffect = Fx.rotateBlock; instantBuild = true; + ignoreBuildDarkness = true; + placeableLiquid = true; } @Override @@ -49,6 +53,11 @@ public class StaticWall extends Prop{ split = large.split(32, 32); } + @Override + public boolean canReplace(Block other){ + return other instanceof StaticWall || super.canReplace(other); + } + boolean eq(int rx, int ry){ return rx < world.width() - 1 && ry < world.height() - 1 && world.tile(rx + 1, ry).block() == this