Editor bugfixes / Median filter
This commit is contained in:
@@ -274,6 +274,8 @@ filter.option.wall = Wall
|
|||||||
filter.option.ore = Ore
|
filter.option.ore = Ore
|
||||||
filter.option.floor2 = Secondary Floor
|
filter.option.floor2 = Secondary Floor
|
||||||
filter.option.threshold2 = Secondary Threshold
|
filter.option.threshold2 = Secondary Threshold
|
||||||
|
filter.option.radius = Radius
|
||||||
|
filter.option.percentile = Percentile
|
||||||
width = Width:
|
width = Width:
|
||||||
height = Height:
|
height = Height:
|
||||||
menu = Menu
|
menu = Menu
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
hide();
|
hide();
|
||||||
//only reset the player; logic.reset() will clear entities, which we do not want
|
//only reset the player; logic.reset() will clear entities, which we do not want
|
||||||
player.reset();
|
player.reset();
|
||||||
state.rules = Gamemode.editor.apply(new Rules());
|
state.rules = Gamemode.editor.apply(lastSavedRules.copy());
|
||||||
world.setMap(new Map(StringMap.of(
|
world.setMap(new Map(StringMap.of(
|
||||||
"name", "Editor Playtesting",
|
"name", "Editor Playtesting",
|
||||||
"width", editor.width(),
|
"width", editor.width(),
|
||||||
|
|||||||
@@ -27,21 +27,22 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class MapGenerateDialog extends FloatingDialog{
|
public class MapGenerateDialog extends FloatingDialog{
|
||||||
|
private final Supplier<GenerateFilter>[] filterTypes = new Supplier[]{NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new, RiverNoiseFilter::new, OreFilter::new, MedianFilter::new};
|
||||||
private final MapEditor editor;
|
private final MapEditor editor;
|
||||||
|
|
||||||
private Pixmap pixmap;
|
private Pixmap pixmap;
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
private GenerateInput input = new GenerateInput();
|
private GenerateInput input = new GenerateInput();
|
||||||
private Array<GenerateFilter> filters = new Array<>();
|
private Array<GenerateFilter> filters = new Array<>();
|
||||||
private int scaling = mobile ? 3 : 1;
|
private int scaling = mobile ? 3 : 1;
|
||||||
private Supplier<GenerateFilter>[] filterTypes = new Supplier[]{NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new, RiverNoiseFilter::new, OreFilter::new};
|
|
||||||
private Table filterTable;
|
private Table filterTable;
|
||||||
|
|
||||||
private AsyncExecutor executor = new AsyncExecutor(1);
|
private AsyncExecutor executor = new AsyncExecutor(1);
|
||||||
private AsyncResult<Void> result;
|
private AsyncResult<Void> result;
|
||||||
private boolean generating;
|
private boolean generating;
|
||||||
private DummyTile returnTile = new DummyTile();
|
private GenTile returnTile = new GenTile();
|
||||||
|
|
||||||
private DummyTile[][] buffer1, buffer2;
|
private GenTile[][] buffer1, buffer2;
|
||||||
|
|
||||||
public MapGenerateDialog(MapEditor editor){
|
public MapGenerateDialog(MapEditor editor){
|
||||||
super("$editor.generate");
|
super("$editor.generate");
|
||||||
@@ -98,12 +99,12 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
rebuildFilters();
|
rebuildFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
DummyTile[][] create(){
|
GenTile[][] create(){
|
||||||
DummyTile[][] out = new DummyTile[editor.width() / scaling][editor.height() / scaling];
|
GenTile[][] out = new GenTile[editor.width() / scaling][editor.height() / scaling];
|
||||||
|
|
||||||
for(int x = 0; x < out.length; x++){
|
for(int x = 0; x < out.length; x++){
|
||||||
for(int y = 0; y < out[0].length; y++){
|
for(int y = 0; y < out[0].length; y++){
|
||||||
out[x][y] = new DummyTile();
|
out[x][y] = new GenTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
@@ -187,7 +188,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
selection.show();
|
selection.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
DummyTile dset(Tile tile){
|
GenTile dset(Tile tile){
|
||||||
returnTile.set(tile);
|
returnTile.set(tile);
|
||||||
return returnTile;
|
return returnTile;
|
||||||
}
|
}
|
||||||
@@ -208,11 +209,11 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//writeback buffer
|
//writeback buffer
|
||||||
DummyTile[][] writeTiles = new DummyTile[editor.width()][editor.height()];
|
GenTile[][] writeTiles = new GenTile[editor.width()][editor.height()];
|
||||||
|
|
||||||
for(int x = 0; x < editor.width(); x++){
|
for(int x = 0; x < editor.width(); x++){
|
||||||
for(int y = 0; y < editor.height(); y++){
|
for(int y = 0; y < editor.height(); y++){
|
||||||
writeTiles[x][y] = new DummyTile();
|
writeTiles[x][y] = new GenTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +234,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
for(int x = 0; x < editor.width(); x++){
|
for(int x = 0; x < editor.width(); x++){
|
||||||
for(int y = 0; y < editor.height(); y++){
|
for(int y = 0; y < editor.height(); y++){
|
||||||
Tile tile = editor.tile(x, y);
|
Tile tile = editor.tile(x, y);
|
||||||
DummyTile write = writeTiles[x][y];
|
GenTile write = writeTiles[x][y];
|
||||||
|
|
||||||
tile.rotation(write.rotation);
|
tile.rotation(write.rotation);
|
||||||
tile.setFloor((Floor)content.block(write.floor));
|
tile.setFloor((Floor)content.block(write.floor));
|
||||||
@@ -278,7 +279,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
for(int px = 0; px < pixmap.getWidth(); px++){
|
||||||
for(int py = 0; py < pixmap.getHeight(); py++){
|
for(int py = 0; py < pixmap.getHeight(); py++){
|
||||||
int x = px * scaling, y = py * scaling;
|
int x = px * scaling, y = py * scaling;
|
||||||
DummyTile tile = buffer1[px][py];
|
GenTile tile = buffer1[px][py];
|
||||||
input.begin(editor, x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
input.begin(editor, x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
||||||
filter.apply(input);
|
filter.apply(input);
|
||||||
buffer2[px][py].set(input.floor, input.block, input.ore, Team.all[tile.team], tile.rotation);
|
buffer2[px][py].set(input.floor, input.block, input.ore, Team.all[tile.team], tile.rotation);
|
||||||
@@ -299,7 +300,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
Tile tile = editor.tile(px * scaling, py * scaling);
|
Tile tile = editor.tile(px * scaling, py * scaling);
|
||||||
color = MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), Team.none);
|
color = MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), Team.none);
|
||||||
}else{
|
}else{
|
||||||
DummyTile tile = buffer1[px][py];
|
GenTile tile = buffer1[px][py];
|
||||||
color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.none);
|
color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.none);
|
||||||
}
|
}
|
||||||
pixmap.drawPixel(px, pixmap.getHeight() - 1 - py, color);
|
pixmap.drawPixel(px, pixmap.getHeight() - 1 - py, color);
|
||||||
@@ -321,7 +322,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DummyTile{
|
public static class GenTile{
|
||||||
public byte team, rotation;
|
public byte team, rotation;
|
||||||
public short block, floor, ore;
|
public short block, floor, ore;
|
||||||
|
|
||||||
@@ -333,7 +334,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
this.rotation = (byte)rotation;
|
this.rotation = (byte)rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(DummyTile other){
|
void set(GenTile other){
|
||||||
this.floor = other.floor;
|
this.floor = other.floor;
|
||||||
this.block = other.block;
|
this.block = other.block;
|
||||||
this.ore = other.ore;
|
this.ore = other.ore;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.anuke.mindustry.editor.generation;
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
import io.anuke.mindustry.editor.MapGenerateDialog.DummyTile;
|
import io.anuke.mindustry.editor.MapGenerateDialog.GenTile;
|
||||||
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
|
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
|
||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
@@ -11,14 +11,14 @@ public class DistortFilter extends GenerateFilter{
|
|||||||
|
|
||||||
{
|
{
|
||||||
options(
|
options(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 400f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 400f),
|
||||||
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
DummyTile tile = in.tile(in.x / (in.scaling) + (noise(in.x, in.y, scl, mag) - mag / 2f) / in.scaling, in.y / (in.scaling) + (noise(in.x, in.y + o, scl, mag) - mag / 2f) / in.scaling);
|
GenTile tile = in.tile(in.x / (in.scaling) + (noise(in.x, in.y, scl, mag) - mag / 2f) / in.scaling, in.y / (in.scaling) + (noise(in.x, in.y + o, scl, mag) - mag / 2f) / in.scaling);
|
||||||
|
|
||||||
in.floor = content.block(tile.floor);
|
in.floor = content.block(tile.floor);
|
||||||
if(!content.block(tile.block).synthetic() && !in.block.synthetic()) in.block = content.block(tile.block);
|
if(!content.block(tile.block).synthetic() && !in.block.synthetic()) in.block = content.block(tile.block);
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import io.anuke.arc.util.noise.RidgedPerlin;
|
|||||||
import io.anuke.arc.util.noise.Simplex;
|
import io.anuke.arc.util.noise.Simplex;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.Blocks;
|
||||||
import io.anuke.mindustry.editor.MapEditor;
|
import io.anuke.mindustry.editor.MapEditor;
|
||||||
import io.anuke.mindustry.editor.MapGenerateDialog.DummyTile;
|
import io.anuke.mindustry.editor.MapGenerateDialog.GenTile;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
public abstract class GenerateFilter{
|
public abstract class GenerateFilter{
|
||||||
protected float o = (float)(Math.random() * 10000000.0);
|
protected transient float o = (float)(Math.random() * 10000000.0);
|
||||||
protected long seed;
|
protected transient long seed;
|
||||||
protected GenerateInput in;
|
protected transient GenerateInput in;
|
||||||
|
|
||||||
public FilterOption[] options;
|
public FilterOption[] options;
|
||||||
|
|
||||||
@@ -88,12 +88,12 @@ public abstract class GenerateFilter{
|
|||||||
pnoise.setSeed((int)(filter.seed + 1));
|
pnoise.setSeed((int)(filter.seed + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
DummyTile tile(float x, float y){
|
GenTile tile(float x, float y){
|
||||||
return buffer.get(Mathf.clamp((int)x, 0, width - 1), Mathf.clamp((int)y, 0, height - 1));
|
return buffer.get(Mathf.clamp((int)x, 0, width - 1), Mathf.clamp((int)y, 0, height - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TileProvider{
|
public interface TileProvider{
|
||||||
DummyTile get(int x, int y);
|
GenTile get(int x, int y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package io.anuke.mindustry.editor.generation;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.IntArray;
|
||||||
|
import io.anuke.arc.math.Mathf;
|
||||||
|
import io.anuke.mindustry.editor.MapGenerateDialog.GenTile;
|
||||||
|
import io.anuke.mindustry.editor.generation.FilterOption.SliderOption;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.content;
|
||||||
|
|
||||||
|
public class MedianFilter extends GenerateFilter{
|
||||||
|
float radius = 2;
|
||||||
|
float percentile = 0.5f;
|
||||||
|
IntArray blocks = new IntArray(), floors = new IntArray();
|
||||||
|
|
||||||
|
{
|
||||||
|
options(
|
||||||
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
||||||
|
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(){
|
||||||
|
int rad = (int)radius;
|
||||||
|
blocks.clear();
|
||||||
|
floors.clear();
|
||||||
|
for(int x = -rad; x <= rad; x++){
|
||||||
|
for(int y = -rad; y <= rad; y++){
|
||||||
|
if(Mathf.dst2(x, y) > rad*rad) continue;
|
||||||
|
|
||||||
|
GenTile tile = in.tile(in.x + x, in.y + y);
|
||||||
|
blocks.add(tile.block);
|
||||||
|
floors.add(tile.floor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
floors.sort();
|
||||||
|
blocks.sort();
|
||||||
|
|
||||||
|
int index = Math.min((int)(floors.size * percentile), floors.size - 1);
|
||||||
|
int floor = floors.get(index), block = blocks.get(index);
|
||||||
|
|
||||||
|
in.floor = content.block(floor);
|
||||||
|
if(!content.block(block).synthetic() && !in.block.synthetic()) in.block = content.block(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user