From cfb01063c0bef07cb1274fc067fa9e3c3602f98f Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 21 Jan 2022 16:32:35 -0500 Subject: [PATCH] Misc map creation utilities --- core/assets/bundles/bundle.properties | 2 + core/src/mindustry/ai/WaveSpawner.java | 2 +- core/src/mindustry/content/Blocks.java | 6 +- core/src/mindustry/content/SectorPresets.java | 16 +++- core/src/mindustry/editor/WaveInfoDialog.java | 76 +++++++++++++++---- .../mindustry/maps/filters/ClearFilter.java | 2 +- .../maps/filters/GenerateFilter.java | 4 + .../mindustry/maps/filters/NoiseFilter.java | 7 +- .../src/mindustry/maps/filters/OreFilter.java | 5 +- .../maps/filters/SpawnPathFilter.java | 12 +-- .../mindustry/maps/filters/TerrainFilter.java | 5 +- .../world/blocks/units/UnitAssembler.java | 2 +- gradle.properties | 2 +- 13 files changed, 105 insertions(+), 36 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 460b756db0..a95a45ffc6 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -395,6 +395,7 @@ waves.title = Waves waves.remove = Remove waves.every = every waves.waves = wave(s) +waves.health = health: {0}% waves.perspawn = per spawn waves.shields = shields/wave waves.to = to @@ -510,6 +511,7 @@ filter.option.circle-scale = Circle Scale filter.option.octaves = Octaves filter.option.falloff = Falloff filter.option.angle = Angle +filter.option.tilt = Tilt filter.option.rotate = Rotate filter.option.amount = Amount filter.option.block = Block diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index d2d780618b..c1947f4da4 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -187,7 +187,7 @@ public class WaveSpawner{ return spawning && !net.client(); } - private void reset(){ + public void reset(){ spawning = false; spawns.clear(); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 376e8b9794..388dc3b412 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -3387,7 +3387,7 @@ public class Blocks{ //TODO requirements tankAssembler = new UnitAssembler("tank-assembler"){{ - requirements(Category.units, with(Items.graphite, 10)); + requirements(Category.units, with(Items.graphite, 600, Items.beryllium, 600, Items.oxide, 200, Items.tungsten, 500)); size = 5; plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 10f, BlockStack.list(Blocks.tungstenWallLarge, 5, Blocks.duct, 2))); consumes.power(2f); @@ -3399,7 +3399,7 @@ public class Blocks{ //TODO requirements shipAssembler = new UnitAssembler("ship-assembler"){{ - requirements(Category.units, with(Items.graphite, 10)); + requirements(Category.units, with(Items.graphite, 600, Items.beryllium, 600, Items.oxide, 200, Items.tungsten, 500)); size = 5; plans.add(new AssemblerUnitPlan(UnitTypes.quell, 60f * 4f, BlockStack.list(Blocks.tungstenWallLarge, 5, Blocks.plasmaBore, 2))); consumes.power(2f); @@ -3412,7 +3412,7 @@ public class Blocks{ //TODO requirements mechAssembler = new UnitAssembler("mech-assembler"){{ - requirements(Category.units, with(Items.graphite, 10)); + requirements(Category.units, with(Items.graphite, 600, Items.carbide, 600, Items.oxide, 200, Items.tungsten, 500)); size = 5; plans.add(new AssemblerUnitPlan(UnitTypes.bulwark, 60f * 4f, BlockStack.list(Blocks.tungstenWallLarge, 5, Blocks.duct, 2))); consumes.power(2f); diff --git a/core/src/mindustry/content/SectorPresets.java b/core/src/mindustry/content/SectorPresets.java index fdd1fe349a..46e5acb258 100644 --- a/core/src/mindustry/content/SectorPresets.java +++ b/core/src/mindustry/content/SectorPresets.java @@ -1,6 +1,5 @@ package mindustry.content; -import mindustry.ctype.*; import mindustry.type.*; import static mindustry.content.Planets.*; @@ -11,7 +10,10 @@ public class SectorPresets{ craters, biomassFacility, frozenForest, ruinousShores, windsweptIslands, stainedMountains, tarFields, fungalPass, extractionOutpost, saltFlats, overgrowth, impact0078, desolateRift, nuclearComplex, planetaryTerminal, - coastline, navalFortress; + coastline, navalFortress, + + onset + ; public static void load(){ //region serpulo @@ -108,5 +110,15 @@ public class SectorPresets{ }}; //endregion + //region erekir + + /* + onset = new SectorPreset("onset", erekir, 15){{ + addStartingItems = true; + captureWave = 10; + difficulty = 1; + }};*/ + + //endreigon } } diff --git a/core/src/mindustry/editor/WaveInfoDialog.java b/core/src/mindustry/editor/WaveInfoDialog.java index 690d467edf..eba91e29b4 100644 --- a/core/src/mindustry/editor/WaveInfoDialog.java +++ b/core/src/mindustry/editor/WaveInfoDialog.java @@ -11,6 +11,7 @@ import arc.scene.ui.TextField.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; +import mindustry.*; import mindustry.content.*; import mindustry.game.*; import mindustry.gen.*; @@ -36,12 +37,16 @@ public class WaveInfoDialog extends BaseDialog{ private Sort sort = Sort.begin; private boolean reverseSort = false; private float updateTimer, updatePeriod = 1f; + private boolean checkedSpawns; private WaveGraph graph = new WaveGraph(); public WaveInfoDialog(){ super("@waves.title"); - shown(this::setup); + shown(() -> { + checkedSpawns = false; + setup(); + }); hidden(() -> state.rules.spawns = groups); addCloseListener(); @@ -321,25 +326,66 @@ public class WaveInfoDialog extends BaseDialog{ //spawn positions are clunky and thus experimental for now if(experimental){ + //health fractions are generally not useful + t.table(p -> { + p.stack(new Slider(0f, 1f, 0.01f, false){{ + setValue(group.healthFraction); + moved(val -> group.healthFraction = val); + }}, new Label("", Styles.outlineLabel){{ + update(() -> setText(Core.bundle.format("waves.health", (int)(group.healthFraction * 100)))); + touchable = Touchable.disabled; + setAlignment(Align.center); + setColor(Color.white); + }}).width(300f).height(44f); + }).row(); + t.table(a -> { - a.add("spawn at "); + a.add("spawn: "); - a.field(group.spawn == -1 ? "" : Point2.x(group.spawn) + "", TextFieldFilter.digitsOnly, text -> { - if(Strings.canParsePositiveInt(text)){ - group.spawn = Point2.pack(Strings.parseInt(text), Point2.y(group.spawn)); - Log.info(group.spawn); + a.button("", () -> { + if(!checkedSpawns){ + //recalculate waves when changed + Vars.spawner.reset(); + checkedSpawns = true; } - }).width(70f); - a.add(","); + BaseDialog dialog = new BaseDialog("Spawn Select"); + dialog.cont.pane(p -> { + p.background(Tex.button).margin(10f); + int i = 0; + int cols = 4; + int max = 20; - a.field(group.spawn == -1 ? "" : Point2.y(group.spawn) + "", TextFieldFilter.digitsOnly, text -> { - if(Strings.canParsePositiveInt(text)){ - group.spawn = Point2.pack(Point2.x(group.spawn), Strings.parseInt(text)); - Log.info(group.spawn); - } - }).width(70f); - }).padBottom(8f).padTop(-8f).row(); + if(spawner.getSpawns().size >= max){ + p.add("[lightgray](first " + max + ")").colspan(cols).padBottom(4).row(); + } + + for(var spawn : spawner.getSpawns()){ + p.button(spawn.x + ", " + spawn.y, Styles.clearTogglet, () -> { + group.spawn = Point2.pack(spawn.x, spawn.y); + dialog.hide(); + }).size(110f, 45f).checked(spawn.pos() == group.spawn); + + if(++i % cols == 0){ + p.row(); + } + + //only display first 20 spawns, you don't need to see more. + if(i >= 20){ + break; + } + } + + if(spawner.getSpawns().isEmpty()){ + p.add("[scarlet]no spawns found in map"); + } + }); + dialog.setFillParent(false); + dialog.addCloseButton(); + dialog.show(); + }).width(160f).height(36f).get().getLabel().setText(() -> group.spawn == -1 ? "" : Point2.x(group.spawn) + ", " + Point2.y(group.spawn)); + + }).padBottom(8f).row(); } } }).width(340f).pad(8); diff --git a/core/src/mindustry/maps/filters/ClearFilter.java b/core/src/mindustry/maps/filters/ClearFilter.java index 59e4512a82..6d9073dba5 100644 --- a/core/src/mindustry/maps/filters/ClearFilter.java +++ b/core/src/mindustry/maps/filters/ClearFilter.java @@ -12,7 +12,7 @@ public class ClearFilter extends GenerateFilter{ @Override public FilterOption[] options(){ - return new BlockOption[]{ + return new FilterOption[]{ new BlockOption("target", () -> target, b -> target = b, anyOptional), new BlockOption("replacement", () -> replace, b -> replace = b, anyOptional) }; diff --git a/core/src/mindustry/maps/filters/GenerateFilter.java b/core/src/mindustry/maps/filters/GenerateFilter.java index 9182fc6857..c8ecdd39bb 100644 --- a/core/src/mindustry/maps/filters/GenerateFilter.java +++ b/core/src/mindustry/maps/filters/GenerateFilter.java @@ -111,6 +111,10 @@ public abstract class GenerateFilter{ return Simplex.noise2d(seed, octaves, persistence, 1f / scl, in.x, in.y) * mag; } + protected float noise(float x, float y, float scl, float mag, float octaves, float persistence){ + return Simplex.noise2d(seed, octaves, persistence, 1f / scl, x, y) * mag; + } + protected float rnoise(float x, float y, float scl, float mag){ return Ridged.noise2d(seed + 1, (int)(x), (int)(y), 1f / scl) * mag; } diff --git a/core/src/mindustry/maps/filters/NoiseFilter.java b/core/src/mindustry/maps/filters/NoiseFilter.java index b4aad342d2..58b0c73161 100644 --- a/core/src/mindustry/maps/filters/NoiseFilter.java +++ b/core/src/mindustry/maps/filters/NoiseFilter.java @@ -7,8 +7,8 @@ import mindustry.world.*; import static mindustry.maps.filters.FilterOption.*; public class NoiseFilter extends GenerateFilter{ - float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f; - Block floor = Blocks.stone, block = Blocks.stoneWall, target = Blocks.air; + public float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f, tilt = 0f; + public Block floor = Blocks.stone, block = Blocks.stoneWall, target = Blocks.air; @Override public FilterOption[] options(){ @@ -17,6 +17,7 @@ public class NoiseFilter extends GenerateFilter{ new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f), new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f), new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f), + new SliderOption("tilt", () -> tilt, f -> tilt = f, -4f, 4f), new BlockOption("target", () -> target, b -> target = b, anyOptional), new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional), new BlockOption("wall", () -> block, b -> block = b, wallsOptional) @@ -30,7 +31,7 @@ public class NoiseFilter extends GenerateFilter{ @Override public void apply(GenerateInput in){ - float noise = noise(in, scl, 1f, octaves, falloff); + float noise = noise(in.x, in.y + in.x * tilt, scl, 1f, octaves, falloff); if(noise > threshold && (target == Blocks.air || in.floor == target || in.block == target)){ if(floor != Blocks.air) in.floor = floor; diff --git a/core/src/mindustry/maps/filters/OreFilter.java b/core/src/mindustry/maps/filters/OreFilter.java index e5fd5f1344..88026783e5 100644 --- a/core/src/mindustry/maps/filters/OreFilter.java +++ b/core/src/mindustry/maps/filters/OreFilter.java @@ -7,7 +7,7 @@ import mindustry.world.*; import static mindustry.maps.filters.FilterOption.*; public class OreFilter extends GenerateFilter{ - public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f; + public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f, tilt = 0f; public Block ore = Blocks.oreCopper, target = Blocks.air; @Override @@ -17,6 +17,7 @@ public class OreFilter extends GenerateFilter{ new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f), new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f), new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f), + new SliderOption("tilt", () -> tilt, f -> tilt = f, -4f, 4f), new BlockOption("ore", () -> ore, b -> ore = b, oresOnly), new BlockOption("target", () -> target, b -> target = b, oresFloorsOptional) }; @@ -29,7 +30,7 @@ public class OreFilter extends GenerateFilter{ @Override public void apply(GenerateInput in){ - float noise = noise(in, scl, 1f, octaves, falloff); + float noise = noise(in.x, in.y + in.x * tilt, scl, 1f, octaves, falloff); if(noise > threshold && in.overlay != Blocks.spawn && (target == Blocks.air || in.floor == target || in.overlay == target) && in.floor.asFloor().hasSurface()){ in.overlay = ore; diff --git a/core/src/mindustry/maps/filters/SpawnPathFilter.java b/core/src/mindustry/maps/filters/SpawnPathFilter.java index 0495baa839..daf1ea8aea 100644 --- a/core/src/mindustry/maps/filters/SpawnPathFilter.java +++ b/core/src/mindustry/maps/filters/SpawnPathFilter.java @@ -7,20 +7,22 @@ import mindustry.*; import mindustry.ai.*; import mindustry.content.*; import mindustry.gen.*; -import mindustry.maps.filters.FilterOption.*; import mindustry.world.*; import mindustry.world.blocks.storage.*; import static mindustry.Vars.*; +import static mindustry.maps.filters.FilterOption.*; /** Selects X spawns from the spawn pool.*/ public class SpawnPathFilter extends GenerateFilter{ - int radius = 3; + public int radius = 3; + public Block block = Blocks.air; @Override public FilterOption[] options(){ - return new SliderOption[]{ - new SliderOption("radius", () -> radius, f -> radius = (int)f, 1, 20).display() + return new FilterOption[]{ + new SliderOption("radius", () -> radius, f -> radius = (int)f, 1, 20).display(), + new BlockOption("wall", () -> block, b -> block = b, wallsOnly) }; } @@ -53,7 +55,7 @@ public class SpawnPathFilter extends GenerateFilter{ if(Structs.inBounds(wx, wy, world.width(), world.height()) && Mathf.within(x, y, radius)){ Tile other = tiles.getn(wx, wy); if(!other.synthetic()){ - other.setBlock(Blocks.air); + other.setBlock(block); } } } diff --git a/core/src/mindustry/maps/filters/TerrainFilter.java b/core/src/mindustry/maps/filters/TerrainFilter.java index 98fdc53d9d..8f05530004 100644 --- a/core/src/mindustry/maps/filters/TerrainFilter.java +++ b/core/src/mindustry/maps/filters/TerrainFilter.java @@ -8,7 +8,7 @@ import mindustry.world.*; import static mindustry.maps.filters.FilterOption.*; public class TerrainFilter extends GenerateFilter{ - float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f; + float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f, tilt = 0f; Block floor = Blocks.air, block = Blocks.stoneWall; @Override @@ -20,6 +20,7 @@ public class TerrainFilter extends GenerateFilter{ new SliderOption("circle-scale", () -> circleScl, f -> circleScl = f, 0f, 3f), new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f), new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f), + new SliderOption("tilt", () -> tilt, f -> tilt = f, -4f, 4f), new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional), new BlockOption("wall", () -> block, b -> block = b, wallsOnly) }; @@ -32,7 +33,7 @@ public class TerrainFilter extends GenerateFilter{ @Override public void apply(GenerateInput in){ - float noise = noise(in, scl, magnitude, octaves, falloff) + Mathf.dst((float)in.x / in.width, (float)in.y / in.height, 0.5f, 0.5f) * circleScl; + float noise = noise(in.x, in.y + in.x * tilt, scl, magnitude, octaves, falloff) + Mathf.dst((float)in.x / in.width, (float)in.y / in.height, 0.5f, 0.5f) * circleScl; if(floor != Blocks.air){ in.floor = floor; diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index 2c20c53789..ed88c6b350 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -73,7 +73,7 @@ public class UnitAssembler extends PayloadBlock{ @Override public boolean canPlaceOn(Tile tile, Team team, int rotation){ - //overlapping construction areas not allowed. + //overlapping construction areas not allowed; grow by a tiny amount so edges can't overlap either. Rect rect = getRect(Tmp.r1, tile.worldx() + offset, tile.worldy() + offset, rotation).grow(0.1f); return !indexer.getFlagged(team, BlockFlag.unitAssembler).contains(b -> getRect(Tmp.r2, b.x, b.y, b.rotation).overlaps(rect)); } diff --git a/gradle.properties b/gradle.properties index c29aaec588..e53e7a150c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,4 @@ android.useAndroidX=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=b139bee16f +archash=35c3b682a1