Unfinished generation tool
This commit is contained in:
BIN
core/assets-raw/sprites/blocks/turrets/scatter.png
Normal file
BIN
core/assets-raw/sprites/blocks/turrets/scatter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 320 B |
@@ -211,6 +211,8 @@ editor.elevation = Elevation
|
|||||||
editor.errorload = Error loading file:\n[accent]{0}
|
editor.errorload = Error loading file:\n[accent]{0}
|
||||||
editor.errorsave = Error saving file:\n[accent]{0}
|
editor.errorsave = Error saving file:\n[accent]{0}
|
||||||
editor.errorname = Map has no name defined.
|
editor.errorname = Map has no name defined.
|
||||||
|
editor.update = Update
|
||||||
|
editor.apply = Apply
|
||||||
editor.generate = Generate
|
editor.generate = Generate
|
||||||
editor.resize = Resize
|
editor.resize = Resize
|
||||||
editor.loadmap = Load Map
|
editor.loadmap = Load Map
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
@@ -1083,7 +1083,7 @@ public class Blocks implements ContentList{
|
|||||||
inaccuracy = 18f;
|
inaccuracy = 18f;
|
||||||
shootCone = 35f;
|
shootCone = 35f;
|
||||||
|
|
||||||
health = 220;
|
health = 220*size*size;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hail = new ArtilleryTurret("hail"){{
|
hail = new ArtilleryTurret("hail"){{
|
||||||
@@ -1301,7 +1301,7 @@ public class Blocks implements ContentList{
|
|||||||
powerUsed = 0.5f;
|
powerUsed = 0.5f;
|
||||||
consumes.powerBuffered(1200f);
|
consumes.powerBuffered(1200f);
|
||||||
range = 160f;
|
range = 160f;
|
||||||
reload = 200f;
|
reload = 170f;
|
||||||
firingMoveFract = 0.1f;
|
firingMoveFract = 0.1f;
|
||||||
shootDuration = 220f;
|
shootDuration = 220f;
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ public class EditorTile extends Tile{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Block previous = floor();
|
Block previous = floor();
|
||||||
Block ore = oreBlock();
|
Block ore = ore();
|
||||||
if(previous == type && ore == Blocks.air) return;
|
if(previous == type && ore == Blocks.air) return;
|
||||||
super.setFloor(type);
|
super.setFloor(type);
|
||||||
//ore may get nullified so make sure to save editrs
|
//ore may get nullified so make sure to save editrs
|
||||||
if(oreBlock() != ore){
|
if(ore() != ore){
|
||||||
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, oreBlock().id));
|
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, ore().id));
|
||||||
}
|
}
|
||||||
if(previous != type){
|
if(previous != type){
|
||||||
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));
|
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public enum EditorTool{
|
|||||||
boolean synth = editor.drawBlock.synthetic();
|
boolean synth = editor.drawBlock.synthetic();
|
||||||
|
|
||||||
Block draw = editor.drawBlock;
|
Block draw = editor.drawBlock;
|
||||||
dest = draw instanceof OreBlock ? tile.oreBlock() : isfloor ? floor : block;
|
dest = draw instanceof OreBlock ? tile.ore() : isfloor ? floor : block;
|
||||||
|
|
||||||
if(dest == draw || block == Blocks.part || block.isMultiblock()){
|
if(dest == draw || block == Blocks.part || block.isMultiblock()){
|
||||||
return;
|
return;
|
||||||
@@ -190,7 +190,7 @@ public enum EditorTool{
|
|||||||
boolean eq(int px, int py){
|
boolean eq(int px, int py){
|
||||||
Tile tile = data.tile(px, py);
|
Tile tile = data.tile(px, py);
|
||||||
|
|
||||||
return (data.drawBlock instanceof OreBlock ? tile.oreBlock() : isfloor ? tile.floor() : tile.block()) == dest && !(data.drawBlock instanceof OreBlock && tile.floor().isLiquid);
|
return (data.drawBlock instanceof OreBlock ? tile.ore() : isfloor ? tile.floor() : tile.block()) == dest && !(data.drawBlock instanceof OreBlock && tile.floor().isLiquid);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
zoom;
|
zoom;
|
||||||
|
|||||||
@@ -224,6 +224,9 @@ public class MapEditor{
|
|||||||
if(drawBlock.synthetic()){
|
if(drawBlock.synthetic()){
|
||||||
tile.setTeam(drawTeam);
|
tile.setTeam(drawTeam);
|
||||||
}
|
}
|
||||||
|
if(drawBlock.rotate){
|
||||||
|
tile.setRotation((byte)rotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
private MapInfoDialog infoDialog;
|
private MapInfoDialog infoDialog;
|
||||||
private MapLoadDialog loadDialog;
|
private MapLoadDialog loadDialog;
|
||||||
private MapResizeDialog resizeDialog;
|
private MapResizeDialog resizeDialog;
|
||||||
|
private MapGenerateDialog generateDialog;
|
||||||
private ScrollPane pane;
|
private ScrollPane pane;
|
||||||
private FloatingDialog menu;
|
private FloatingDialog menu;
|
||||||
private boolean saved = false;
|
private boolean saved = false;
|
||||||
@@ -50,8 +51,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
|
|
||||||
editor = new MapEditor();
|
editor = new MapEditor();
|
||||||
view = new MapView(editor);
|
view = new MapView(editor);
|
||||||
|
|
||||||
infoDialog = new MapInfoDialog(editor);
|
infoDialog = new MapInfoDialog(editor);
|
||||||
|
generateDialog = new MapGenerateDialog(editor);
|
||||||
|
|
||||||
menu = new FloatingDialog("$menu");
|
menu = new FloatingDialog("$menu");
|
||||||
menu.addCloseButton();
|
menu.addCloseButton();
|
||||||
@@ -62,15 +63,20 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
menu.cont.table(t -> {
|
menu.cont.table(t -> {
|
||||||
t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5);
|
t.defaults().size(swidth, 60f).padBottom(5).padRight(5).padLeft(5);
|
||||||
|
|
||||||
t.addImageTextButton("$editor.savemap", "icon-floppy-16", isize, this::save).size(swidth * 2f + 10, 60f).colspan(2);
|
t.addImageTextButton("$editor.savemap", "icon-floppy-16", isize, this::save);
|
||||||
|
|
||||||
t.row();
|
|
||||||
|
|
||||||
t.addImageTextButton("$editor.mapinfo", "icon-pencil", isize, () -> {
|
t.addImageTextButton("$editor.mapinfo", "icon-pencil", isize, () -> {
|
||||||
infoDialog.show();
|
infoDialog.show();
|
||||||
menu.hide();
|
menu.hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
t.row();
|
||||||
|
|
||||||
|
t.addImageTextButton("$editor.generate", "icon-editor", isize, () -> {
|
||||||
|
generateDialog.show();
|
||||||
|
menu.hide();
|
||||||
|
});
|
||||||
|
|
||||||
t.addImageTextButton("$editor.resize", "icon-resize", isize, () -> {
|
t.addImageTextButton("$editor.resize", "icon-resize", isize, () -> {
|
||||||
resizeDialog.show();
|
resizeDialog.show();
|
||||||
menu.hide();
|
menu.hide();
|
||||||
|
|||||||
167
core/src/io/anuke/mindustry/editor/MapGenerateDialog.java
Normal file
167
core/src/io/anuke/mindustry/editor/MapGenerateDialog.java
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.Array;
|
||||||
|
import io.anuke.arc.graphics.Pixmap;
|
||||||
|
import io.anuke.arc.graphics.Pixmap.Format;
|
||||||
|
import io.anuke.arc.graphics.Texture;
|
||||||
|
import io.anuke.arc.scene.Element;
|
||||||
|
import io.anuke.arc.scene.ui.layout.Table;
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption;
|
||||||
|
import io.anuke.mindustry.editor.generation.GenerateFilter;
|
||||||
|
import io.anuke.mindustry.editor.generation.GenerateFilter.GenerateInput;
|
||||||
|
import io.anuke.mindustry.editor.generation.NoiseFilter;
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
|
import io.anuke.mindustry.io.MapIO;
|
||||||
|
import io.anuke.mindustry.ui.BorderImage;
|
||||||
|
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||||
|
import io.anuke.mindustry.world.DummyTile;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
|
public class MapGenerateDialog extends FloatingDialog{
|
||||||
|
private final MapEditor editor;
|
||||||
|
private Pixmap pixmap;
|
||||||
|
private Texture texture;
|
||||||
|
private GenerateInput input = new GenerateInput();
|
||||||
|
private Array<GenerateFilter> filters = new Array<>();
|
||||||
|
|
||||||
|
public MapGenerateDialog(MapEditor editor){
|
||||||
|
super("editor.generate");
|
||||||
|
this.editor = editor;
|
||||||
|
|
||||||
|
shown(this::setup);
|
||||||
|
addCloseButton();
|
||||||
|
buttons.addButton("$editor.apply", () -> {
|
||||||
|
apply();
|
||||||
|
hide();
|
||||||
|
}).size(180f, 64f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
if(pixmap != null){
|
||||||
|
pixmap.dispose();
|
||||||
|
texture.dispose();
|
||||||
|
pixmap = null;
|
||||||
|
texture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap = new Pixmap(editor.width(), editor.height(), Format.RGBA8888);
|
||||||
|
texture = new Texture(pixmap);
|
||||||
|
|
||||||
|
cont.clear();
|
||||||
|
cont.table("flat", t -> {
|
||||||
|
t.margin(8f);
|
||||||
|
t.add(new BorderImage(texture)).size(500f).padRight(6);
|
||||||
|
t.table(right -> {
|
||||||
|
Table[] fs = {null};
|
||||||
|
Runnable rebuild = () -> {
|
||||||
|
Table p = fs[0];
|
||||||
|
p.clearChildren();
|
||||||
|
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
p.table("button", f -> {
|
||||||
|
f.left();
|
||||||
|
for(FilterOption option : filter.options){
|
||||||
|
option.build(f);
|
||||||
|
f.row();
|
||||||
|
}
|
||||||
|
for(Element e : f.getChildren()){
|
||||||
|
e.changed(this::update);
|
||||||
|
}
|
||||||
|
}).pad(3).width(280f);
|
||||||
|
p.row();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
right.pane(p -> {
|
||||||
|
p.top();
|
||||||
|
fs[0] = p;
|
||||||
|
}).fill().width(300f).growY().get().setScrollingDisabled(true, false);
|
||||||
|
right.row();
|
||||||
|
right.addButton("$add", () -> {
|
||||||
|
filters.add(new NoiseFilter());
|
||||||
|
rebuild.run();
|
||||||
|
}).fillX().height(50f);
|
||||||
|
}).grow();
|
||||||
|
|
||||||
|
t.row();
|
||||||
|
t.addButton("$editor.update", () -> {
|
||||||
|
input.randomize();
|
||||||
|
update();
|
||||||
|
}).size(300f, 66f).colspan(2).pad(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(){
|
||||||
|
Tile[][] writeTiles = new Tile[editor.width()][editor.height()];
|
||||||
|
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
writeTiles[x][y] = new DummyTile(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
Tile write = writeTiles[x][y];
|
||||||
|
input.begin(editor, x, y, tile.floor(), tile.block(), tile.ore());
|
||||||
|
filter.apply(input);
|
||||||
|
write.setRotation(tile.getRotation());
|
||||||
|
write.setOre(input.ore);
|
||||||
|
write.setFloor((Floor)input.floor);
|
||||||
|
write.setBlock(input.block);
|
||||||
|
write.setTeam(tile.getTeam());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.load(() -> {
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
Tile write = writeTiles[x][y];
|
||||||
|
|
||||||
|
tile.setRotation(write.getRotation());
|
||||||
|
tile.setOre(write.ore());
|
||||||
|
tile.setFloor(write.floor());
|
||||||
|
tile.setBlock(write.block());
|
||||||
|
tile.setTeam(write.getTeam());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.renderer().updateAll();
|
||||||
|
editor.clearOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(){
|
||||||
|
|
||||||
|
boolean modified = false;
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
modified = true;
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
input.begin(editor, x, y, tile.floor(), tile.block(), tile.ore());
|
||||||
|
filter.apply(input);
|
||||||
|
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, MapIO.colorFor(input.floor, input.block, input.ore, Team.none));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!modified){
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), Team.none));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.draw(pixmap, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -139,8 +139,8 @@ public class MapRenderer implements Disposable{
|
|||||||
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
|
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
|
||||||
offsetX = tilesize/2f - region.getWidth()/2f * Draw.scl;
|
offsetX = tilesize/2f - region.getWidth()/2f * Draw.scl;
|
||||||
offsetY = tilesize/2f - region.getHeight()/2f * Draw.scl;
|
offsetY = tilesize/2f - region.getHeight()/2f * Draw.scl;
|
||||||
}else if(wall == Blocks.air && tile.oreBlock() != null){
|
}else if(wall == Blocks.air && tile.ore() != null){
|
||||||
region = tile.oreBlock().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.oreBlock().editorVariantRegions().length-1)];;
|
region = tile.ore().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.ore().editorVariantRegions().length-1)];;
|
||||||
}else{
|
}else{
|
||||||
region = Core.atlas.find("clear-editor");
|
region = Core.atlas.find("clear-editor");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ public class WaveInfoDialog extends FloatingDialog{
|
|||||||
preview.clear();
|
preview.clear();
|
||||||
preview.top();
|
preview.top();
|
||||||
|
|
||||||
Array<SpawnGroup> groups = (this.groups == null ? DefaultWaves.getDefaultSpawns() : this.groups);
|
Array<SpawnGroup> groups = (this.groups == null ? DefaultWaves.get() : this.groups);
|
||||||
|
|
||||||
for(int i = start; i < displayed + start; i ++){
|
for(int i = start; i < displayed + start; i ++){
|
||||||
int wave = i;
|
int wave = i;
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
|
public class DistortFilter extends GenerateFilter{
|
||||||
|
float scl = 40, mag = 5;
|
||||||
|
|
||||||
|
{
|
||||||
|
options(
|
||||||
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 1000f),
|
||||||
|
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 10f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(){
|
||||||
|
Tile tile = in.tile(in.x + noise(in.x, in.y, scl, mag)-mag/2f, in.y + noise(in.x, in.y+o, scl, mag)-mag/2f);
|
||||||
|
|
||||||
|
in.floor = tile.floor();
|
||||||
|
if(!tile.block().synthetic() && !in.block.synthetic()) in.block = tile.block();
|
||||||
|
in.ore = tile.ore();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.arc.Core;
|
||||||
|
import io.anuke.arc.function.*;
|
||||||
|
import io.anuke.arc.scene.style.TextureRegionDrawable;
|
||||||
|
import io.anuke.arc.scene.ui.layout.Table;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.Block.Icon;
|
||||||
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
import io.anuke.mindustry.world.blocks.OreBlock;
|
||||||
|
|
||||||
|
public abstract class FilterOption{
|
||||||
|
public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OreBlock)) && Core.atlas.isFound(b.icon(Icon.full));
|
||||||
|
public static final Predicate<Block> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Icon.full));
|
||||||
|
|
||||||
|
public abstract void build(Table table);
|
||||||
|
|
||||||
|
static class SliderOption extends FilterOption{
|
||||||
|
final String name;
|
||||||
|
final FloatProvider getter;
|
||||||
|
final FloatConsumer setter;
|
||||||
|
final float min, max;
|
||||||
|
|
||||||
|
SliderOption(String name, FloatProvider getter, FloatConsumer setter, float min, float max){
|
||||||
|
this.name = name;
|
||||||
|
this.getter = getter;
|
||||||
|
this.setter = setter;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
table.add(name);
|
||||||
|
table.row();
|
||||||
|
table.addSlider(min, max, (max-min)/100f, setter).get().setValue(getter.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class BlockOption extends FilterOption{
|
||||||
|
final String name;
|
||||||
|
final Supplier<Block> supplier;
|
||||||
|
final Consumer<Block> consumer;
|
||||||
|
final Predicate<Block> filter;
|
||||||
|
|
||||||
|
BlockOption(String name, Supplier<Block> supplier, Consumer<Block> consumer, Predicate<Block> filter){
|
||||||
|
this.name = name;
|
||||||
|
this.supplier = supplier;
|
||||||
|
this.consumer = consumer;
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
table.add(name + ": ");
|
||||||
|
table.addButton(b -> {
|
||||||
|
b.addImage(supplier.get().icon(Icon.small)).update(i -> ((TextureRegionDrawable)i.getDrawable()).setRegion(supplier.get().icon(Icon.small))).size(8*3);
|
||||||
|
}, () -> {
|
||||||
|
FloatingDialog dialog = new FloatingDialog("");
|
||||||
|
dialog.setFillParent(false);
|
||||||
|
int i = 0;
|
||||||
|
for(Block block : Vars.content.blocks()){
|
||||||
|
if(!filter.test(block)) continue;
|
||||||
|
|
||||||
|
dialog.cont.addImage(block.icon(Icon.medium)).size(8*4).pad(3).get().clicked(() -> {
|
||||||
|
consumer.accept(block);
|
||||||
|
dialog.hide();
|
||||||
|
});
|
||||||
|
if(++i % 10 == 0) dialog.cont.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.arc.math.Mathf;
|
||||||
|
import io.anuke.arc.util.noise.Simplex;
|
||||||
|
import io.anuke.mindustry.editor.MapEditor;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
|
public abstract class GenerateFilter{
|
||||||
|
protected float o = (float)(Math.random()*10000000.0);
|
||||||
|
protected GenerateInput in;
|
||||||
|
|
||||||
|
public FilterOption[] options;
|
||||||
|
|
||||||
|
protected abstract void apply();
|
||||||
|
|
||||||
|
protected float noise(float x, float y, float scl, float mag){
|
||||||
|
return (float)in.noise.octaveNoise2D(1f, 0f, 1f/scl, x + o, y + o)*mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float noise(float x, float y, float scl, float mag, float octaves, float persistence){
|
||||||
|
return (float)in.noise.octaveNoise2D(octaves, persistence, 1f/scl, x + o, y + o)*mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void options(FilterOption... options){
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void apply(GenerateInput in){
|
||||||
|
this.in = in;
|
||||||
|
apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GenerateInput{
|
||||||
|
public Floor srcfloor;
|
||||||
|
public Block srcblock;
|
||||||
|
public Block srcore;
|
||||||
|
public int x, y;
|
||||||
|
|
||||||
|
public MapEditor editor;
|
||||||
|
public Block floor, block, ore;
|
||||||
|
|
||||||
|
Simplex noise = new Simplex();
|
||||||
|
|
||||||
|
public void begin(MapEditor editor, int x, int y, Block floor, Block block, Block ore){
|
||||||
|
this.editor = editor;
|
||||||
|
this.floor = this.srcfloor = (Floor)floor;
|
||||||
|
this.block = this.srcblock = block;
|
||||||
|
this.ore = srcore = ore;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void randomize(){
|
||||||
|
noise.setSeed(Mathf.random(99999999));
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile tile(double x, double y){
|
||||||
|
return editor.tile((int)Mathf.clamp(x, 0, editor.width() - 1), (int)Mathf.clamp(y, 0, editor.height() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.content.Blocks;
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption.BlockOption;
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.editor.generation.FilterOption.floorsOnly;
|
||||||
|
import static io.anuke.mindustry.editor.generation.FilterOption.wallsOnly;
|
||||||
|
|
||||||
|
public class NoiseFilter extends GenerateFilter{
|
||||||
|
float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f;
|
||||||
|
Block floor = Blocks.stone, block = Blocks.rocks;
|
||||||
|
|
||||||
|
{
|
||||||
|
options(
|
||||||
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 100f),
|
||||||
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
|
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 20f),
|
||||||
|
new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f),
|
||||||
|
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
|
||||||
|
new BlockOption("wall", () -> block, b -> block = b, wallsOnly)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(){
|
||||||
|
float noise = noise(in.x, in.y, scl, 1f, octaves, falloff);
|
||||||
|
|
||||||
|
if(noise > threshold){
|
||||||
|
in.floor = floor;
|
||||||
|
if(wallsOnly.test(in.srcblock)) in.block = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,159 +9,158 @@ import io.anuke.mindustry.type.ItemStack;
|
|||||||
public class DefaultWaves{
|
public class DefaultWaves{
|
||||||
private static Array<SpawnGroup> spawns;
|
private static Array<SpawnGroup> spawns;
|
||||||
|
|
||||||
public static Array<SpawnGroup> getDefaultSpawns(){
|
public static Array<SpawnGroup> get(){
|
||||||
if(spawns == null && UnitTypes.dagger != null){
|
if(spawns == null && UnitTypes.dagger != null){
|
||||||
spawns = Array.with(
|
spawns = Array.with(
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
end = 8;
|
end = 8;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.wraith){{
|
new SpawnGroup(UnitTypes.wraith){{
|
||||||
begin = 12;
|
begin = 12;
|
||||||
end = 14;
|
end = 14;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 11;
|
begin = 11;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
max = 4;
|
max = 4;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.titan){{
|
new SpawnGroup(UnitTypes.titan){{
|
||||||
begin = 9;
|
begin = 9;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
|
|
||||||
end = 30;
|
end = 30;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 10;
|
begin = 8;
|
||||||
unitScaling = 2;
|
unitScaling = 1;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
end = 30;
|
end = 30;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.titan){{
|
new SpawnGroup(UnitTypes.titan){{
|
||||||
begin = 28;
|
begin = 28;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 1;
|
unitScaling = 1;
|
||||||
end = 40;
|
end = 40;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.titan){{
|
new SpawnGroup(UnitTypes.titan){{
|
||||||
begin = 45;
|
begin = 45;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitScaling = 2;
|
unitScaling = 2;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.titan){{
|
new SpawnGroup(UnitTypes.titan){{
|
||||||
begin = 120;
|
begin = 120;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
unitAmount = 5;
|
unitAmount = 5;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.wraith){{
|
new SpawnGroup(UnitTypes.wraith){{
|
||||||
begin = 16;
|
begin = 16;
|
||||||
unitScaling = 2;
|
unitScaling = 1;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
|
|
||||||
end = 39;
|
max = 7;
|
||||||
max = 7;
|
}},
|
||||||
}},
|
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 82;
|
begin = 82;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 41;
|
begin = 41;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
unitAmount = 1;
|
unitAmount = 1;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
effect = StatusEffects.shielded;
|
effect = StatusEffects.shielded;
|
||||||
max = 10;
|
max = 10;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.fortress){{
|
new SpawnGroup(UnitTypes.fortress){{
|
||||||
begin = 40;
|
begin = 40;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
max = 10;
|
max = 10;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 35;
|
begin = 35;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
items = new ItemStack(Items.blastCompound, 60);
|
items = new ItemStack(Items.blastCompound, 60);
|
||||||
end = 60;
|
end = 60;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.dagger){{
|
new SpawnGroup(UnitTypes.dagger){{
|
||||||
begin = 42;
|
begin = 42;
|
||||||
spacing = 3;
|
spacing = 3;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
items = new ItemStack(Items.pyratite, 100);
|
items = new ItemStack(Items.pyratite, 100);
|
||||||
end = 130;
|
end = 130;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.ghoul){{
|
new SpawnGroup(UnitTypes.ghoul){{
|
||||||
begin = 40;
|
begin = 40;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
spacing = 2;
|
spacing = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
max = 8;
|
max = 8;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.wraith){{
|
new SpawnGroup(UnitTypes.wraith){{
|
||||||
begin = 50;
|
begin = 50;
|
||||||
unitAmount = 4;
|
unitAmount = 4;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
effect = StatusEffects.overdrive;
|
effect = StatusEffects.overdrive;
|
||||||
max = 8;
|
max = 8;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.revenant){{
|
new SpawnGroup(UnitTypes.revenant){{
|
||||||
begin = 50;
|
begin = 50;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
max = 8;
|
max = 8;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.ghoul){{
|
new SpawnGroup(UnitTypes.ghoul){{
|
||||||
begin = 53;
|
begin = 53;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
spacing = 4;
|
spacing = 4;
|
||||||
max = 8;
|
max = 8;
|
||||||
end = 74;
|
end = 74;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new SpawnGroup(UnitTypes.ghoul){{
|
new SpawnGroup(UnitTypes.ghoul){{
|
||||||
begin = 53;
|
begin = 53;
|
||||||
unitAmount = 2;
|
unitAmount = 2;
|
||||||
unitScaling = 3;
|
unitScaling = 3;
|
||||||
spacing = 4;
|
spacing = 4;
|
||||||
max = 8;
|
max = 8;
|
||||||
end = 74;
|
end = 74;
|
||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return spawns == null ? new Array<>() : spawns;
|
return spawns == null ? new Array<>() : spawns;
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ public enum RulePreset{
|
|||||||
waveTimer = true;
|
waveTimer = true;
|
||||||
waves = true;
|
waves = true;
|
||||||
unitDrops = true;
|
unitDrops = true;
|
||||||
spawns = DefaultWaves.getDefaultSpawns();
|
spawns = DefaultWaves.get();
|
||||||
}}),
|
}}),
|
||||||
sandbox(() -> new Rules(){{
|
sandbox(() -> new Rules(){{
|
||||||
infiniteResources = true;
|
infiniteResources = true;
|
||||||
waves = true;
|
waves = true;
|
||||||
waveTimer = false;
|
waveTimer = false;
|
||||||
spawns = DefaultWaves.getDefaultSpawns();
|
spawns = DefaultWaves.get();
|
||||||
}}),
|
}}),
|
||||||
attack(() -> new Rules(){{
|
attack(() -> new Rules(){{
|
||||||
enemyCheat = true;
|
enemyCheat = true;
|
||||||
|
|||||||
@@ -28,5 +28,5 @@ public class Rules{
|
|||||||
/**Zone ID, -1 for invalid zone.*/
|
/**Zone ID, -1 for invalid zone.*/
|
||||||
public byte zone = -1;
|
public byte zone = -1;
|
||||||
/**Spawn layout. Since only zones modify this, it should be assigned on save load.*/
|
/**Spawn layout. Since only zones modify this, it should be assigned on save load.*/
|
||||||
public transient Array<SpawnGroup> spawns = DefaultWaves.getDefaultSpawns();
|
public transient Array<SpawnGroup> spawns = DefaultWaves.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class MinimapRenderer implements Disposable{
|
|||||||
|
|
||||||
private int colorFor(Tile tile){
|
private int colorFor(Tile tile){
|
||||||
tile = tile.target();
|
tile = tile.target();
|
||||||
return MapIO.colorFor(tile.floor(), tile.block(), tile.oreBlock(), tile.getTeam());
|
return MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), tile.getTeam());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class MapIO{
|
|||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles[x][y];
|
||||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.oreBlock(), tile.getTeam()));
|
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.ore(), tile.getTeam()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pixmap;
|
return pixmap;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import io.anuke.mindustry.io.MapIO;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class Map{
|
public class Map implements Comparable<Map>{
|
||||||
/** Whether this is a custom map.*/
|
/** Whether this is a custom map.*/
|
||||||
public final boolean custom;
|
public final boolean custom;
|
||||||
/** Metadata. Author description, display name, etc.*/
|
/** Metadata. Author description, display name, etc.*/
|
||||||
@@ -54,10 +54,10 @@ public class Map{
|
|||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.err("Malformed waves: {0}", tags.get("waves"));
|
Log.err("Malformed waves: {0}", tags.get("waves"));
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return DefaultWaves.getDefaultSpawns();
|
return DefaultWaves.get();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
return DefaultWaves.getDefaultSpawns();
|
return DefaultWaves.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +90,16 @@ public class Map{
|
|||||||
return tags.containsKey(name);
|
return tags.containsKey(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Map map){
|
||||||
|
int type = -Boolean.compare(custom, map.custom);
|
||||||
|
if(type != 0){
|
||||||
|
return type;
|
||||||
|
}else{
|
||||||
|
return name().compareTo(map.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "Map{" +
|
return "Map{" +
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public class Maps implements Disposable{
|
|||||||
map.texture = new Texture(MapIO.generatePreview(data));
|
map.texture = new Texture(MapIO.generatePreview(data));
|
||||||
}
|
}
|
||||||
maps.add(map);
|
maps.add(map);
|
||||||
|
maps.sort();
|
||||||
}catch(IOException e){
|
}catch(IOException e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -181,6 +182,7 @@ public class Maps implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
maps.add(map);
|
maps.add(map);
|
||||||
|
maps.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCustomMaps(){
|
private void loadCustomMaps(){
|
||||||
|
|||||||
@@ -340,6 +340,6 @@ public class PlacementFragment extends Fragment{
|
|||||||
|
|
||||||
/** Returns the block currently being hovered over in the world. */
|
/** Returns the block currently being hovered over in the world. */
|
||||||
Block tileDisplayBlock(){
|
Block tileDisplayBlock(){
|
||||||
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.oreBlock() != Blocks.air ? hoverTile.oreBlock() : null;
|
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.ore() != Blocks.air ? hoverTile.ore() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
25
core/src/io/anuke/mindustry/world/DummyTile.java
Normal file
25
core/src/io/anuke/mindustry/world/DummyTile.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
|
|
||||||
|
public class DummyTile extends Tile{
|
||||||
|
|
||||||
|
public DummyTile(int x, int y){
|
||||||
|
super(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Team getTeam(){
|
||||||
|
return Team.all[getTeamID()];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void changed(){
|
||||||
|
//nothing matters
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preChanged(){
|
||||||
|
//it really doesn't
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -345,7 +345,7 @@ public class Tile implements Position, TargetTrait{
|
|||||||
this.ore = 0;
|
this.ore = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Floor oreBlock(){
|
public Floor ore(){
|
||||||
return (Floor)content.block(ore);
|
return (Floor)content.block(ore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ public class BlockPart extends Block{
|
|||||||
hasPower = hasItems = hasLiquids = true;
|
hasPower = hasItems = hasLiquids = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean synthetic(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHidden(){
|
public boolean isHidden(){
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class Floor extends Block{
|
|||||||
Mathf.random.setSeed(tile.pos());
|
Mathf.random.setSeed(tile.pos());
|
||||||
|
|
||||||
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
||||||
Floor floor = tile.oreBlock();
|
Floor floor = tile.ore();
|
||||||
if(floor != Blocks.air && floor != this){ //ore should never have itself on top, but it's possible, so prevent a crash in that case
|
if(floor != Blocks.air && floor != this){ //ore should never have itself on top, but it's possible, so prevent a crash in that case
|
||||||
floor.draw(tile);
|
floor.draw(tile);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user