Unfinished generation tool

This commit is contained in:
Anuken
2019-03-15 00:13:54 -04:00
parent 43bcf0cf3b
commit 7d1a8f5404
28 changed files with 575 additions and 156 deletions

View File

@@ -1083,7 +1083,7 @@ public class Blocks implements ContentList{
inaccuracy = 18f;
shootCone = 35f;
health = 220;
health = 220*size*size;
}};
hail = new ArtilleryTurret("hail"){{
@@ -1301,7 +1301,7 @@ public class Blocks implements ContentList{
powerUsed = 0.5f;
consumes.powerBuffered(1200f);
range = 160f;
reload = 200f;
reload = 170f;
firingMoveFract = 0.1f;
shootDuration = 220f;

View File

@@ -35,12 +35,12 @@ public class EditorTile extends Tile{
}
Block previous = floor();
Block ore = oreBlock();
Block ore = ore();
if(previous == type && ore == Blocks.air) return;
super.setFloor(type);
//ore may get nullified so make sure to save editrs
if(oreBlock() != ore){
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, oreBlock().id));
if(ore() != ore){
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, ore().id));
}
if(previous != type){
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));

View File

@@ -101,7 +101,7 @@ public enum EditorTool{
boolean synth = editor.drawBlock.synthetic();
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()){
return;
@@ -190,7 +190,7 @@ public enum EditorTool{
boolean eq(int px, int 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;

View File

@@ -224,6 +224,9 @@ public class MapEditor{
if(drawBlock.synthetic()){
tile.setTeam(drawTeam);
}
if(drawBlock.rotate){
tile.setRotation((byte)rotation);
}
}
}
}

View File

@@ -37,6 +37,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
private MapInfoDialog infoDialog;
private MapLoadDialog loadDialog;
private MapResizeDialog resizeDialog;
private MapGenerateDialog generateDialog;
private ScrollPane pane;
private FloatingDialog menu;
private boolean saved = false;
@@ -50,8 +51,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor = new MapEditor();
view = new MapView(editor);
infoDialog = new MapInfoDialog(editor);
generateDialog = new MapGenerateDialog(editor);
menu = new FloatingDialog("$menu");
menu.addCloseButton();
@@ -62,15 +63,20 @@ public class MapEditorDialog extends Dialog implements Disposable{
menu.cont.table(t -> {
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.row();
t.addImageTextButton("$editor.savemap", "icon-floppy-16", isize, this::save);
t.addImageTextButton("$editor.mapinfo", "icon-pencil", isize, () -> {
infoDialog.show();
menu.hide();
});
t.row();
t.addImageTextButton("$editor.generate", "icon-editor", isize, () -> {
generateDialog.show();
menu.hide();
});
t.addImageTextButton("$editor.resize", "icon-resize", isize, () -> {
resizeDialog.show();
menu.hide();

View 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);
}
}

View File

@@ -139,8 +139,8 @@ public class MapRenderer implements Disposable{
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
offsetX = tilesize/2f - region.getWidth()/2f * Draw.scl;
offsetY = tilesize/2f - region.getHeight()/2f * Draw.scl;
}else if(wall == Blocks.air && tile.oreBlock() != null){
region = tile.oreBlock().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.oreBlock().editorVariantRegions().length-1)];;
}else if(wall == Blocks.air && tile.ore() != null){
region = tile.ore().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.ore().editorVariantRegions().length-1)];;
}else{
region = Core.atlas.find("clear-editor");
}

View File

@@ -200,7 +200,7 @@ public class WaveInfoDialog extends FloatingDialog{
preview.clear();
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 ++){
int wave = i;

View File

@@ -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();
}
}

View File

@@ -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();
});
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -9,159 +9,158 @@ import io.anuke.mindustry.type.ItemStack;
public class DefaultWaves{
private static Array<SpawnGroup> spawns;
public static Array<SpawnGroup> getDefaultSpawns(){
public static Array<SpawnGroup> get(){
if(spawns == null && UnitTypes.dagger != null){
spawns = Array.with(
new SpawnGroup(UnitTypes.dagger){{
end = 8;
unitScaling = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
end = 8;
unitScaling = 2;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 12;
end = 14;
unitScaling = 2;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 12;
end = 14;
unitScaling = 2;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 11;
unitScaling = 2;
spacing = 2;
max = 4;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 11;
unitScaling = 2;
spacing = 2;
max = 4;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 9;
spacing = 3;
unitScaling = 2;
new SpawnGroup(UnitTypes.titan){{
begin = 9;
spacing = 3;
unitScaling = 2;
end = 30;
}},
end = 30;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 10;
unitScaling = 2;
unitAmount = 1;
spacing = 2;
end = 30;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 8;
unitScaling = 1;
unitAmount = 1;
spacing = 2;
end = 30;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 28;
spacing = 3;
unitScaling = 1;
end = 40;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 28;
spacing = 3;
unitScaling = 1;
end = 40;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 45;
spacing = 3;
unitScaling = 2;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 45;
spacing = 3;
unitScaling = 2;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 120;
spacing = 2;
unitScaling = 3;
unitAmount = 5;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 120;
spacing = 2;
unitScaling = 3;
unitAmount = 5;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 16;
unitScaling = 2;
spacing = 2;
new SpawnGroup(UnitTypes.wraith){{
begin = 16;
unitScaling = 1;
spacing = 2;
end = 39;
max = 7;
}},
max = 7;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 82;
spacing = 3;
unitAmount = 4;
unitScaling = 3;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 82;
spacing = 3;
unitAmount = 4;
unitScaling = 3;
effect = StatusEffects.overdrive;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 41;
spacing = 5;
unitAmount = 1;
unitScaling = 3;
effect = StatusEffects.shielded;
max = 10;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 41;
spacing = 5;
unitAmount = 1;
unitScaling = 3;
effect = StatusEffects.shielded;
max = 10;
}},
new SpawnGroup(UnitTypes.fortress){{
begin = 40;
spacing = 5;
unitAmount = 2;
unitScaling = 3;
max = 10;
}},
new SpawnGroup(UnitTypes.fortress){{
begin = 40;
spacing = 5;
unitAmount = 2;
unitScaling = 3;
max = 10;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 35;
spacing = 3;
unitAmount = 4;
effect = StatusEffects.overdrive;
items = new ItemStack(Items.blastCompound, 60);
end = 60;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 35;
spacing = 3;
unitAmount = 4;
effect = StatusEffects.overdrive;
items = new ItemStack(Items.blastCompound, 60);
end = 60;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 42;
spacing = 3;
unitAmount = 4;
effect = StatusEffects.overdrive;
items = new ItemStack(Items.pyratite, 100);
end = 130;
}},
new SpawnGroup(UnitTypes.dagger){{
begin = 42;
spacing = 3;
unitAmount = 4;
effect = StatusEffects.overdrive;
items = new ItemStack(Items.pyratite, 100);
end = 130;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 40;
unitAmount = 2;
spacing = 2;
unitScaling = 3;
max = 8;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 40;
unitAmount = 2;
spacing = 2;
unitScaling = 3;
max = 8;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 50;
unitAmount = 4;
unitScaling = 3;
spacing = 5;
effect = StatusEffects.overdrive;
max = 8;
}},
new SpawnGroup(UnitTypes.wraith){{
begin = 50;
unitAmount = 4;
unitScaling = 3;
spacing = 5;
effect = StatusEffects.overdrive;
max = 8;
}},
new SpawnGroup(UnitTypes.revenant){{
begin = 50;
unitAmount = 2;
unitScaling = 3;
spacing = 5;
max = 8;
}},
new SpawnGroup(UnitTypes.revenant){{
begin = 50;
unitAmount = 2;
unitScaling = 3;
spacing = 5;
max = 8;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 53;
unitAmount = 2;
unitScaling = 3;
spacing = 4;
max = 8;
end = 74;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 53;
unitAmount = 2;
unitScaling = 3;
spacing = 4;
max = 8;
end = 74;
}},
new SpawnGroup(UnitTypes.ghoul){{
begin = 53;
unitAmount = 2;
unitScaling = 3;
spacing = 4;
max = 8;
end = 74;
}}
new SpawnGroup(UnitTypes.ghoul){{
begin = 53;
unitAmount = 2;
unitScaling = 3;
spacing = 4;
max = 8;
end = 74;
}}
);
}
return spawns == null ? new Array<>() : spawns;

View File

@@ -9,13 +9,13 @@ public enum RulePreset{
waveTimer = true;
waves = true;
unitDrops = true;
spawns = DefaultWaves.getDefaultSpawns();
spawns = DefaultWaves.get();
}}),
sandbox(() -> new Rules(){{
infiniteResources = true;
waves = true;
waveTimer = false;
spawns = DefaultWaves.getDefaultSpawns();
spawns = DefaultWaves.get();
}}),
attack(() -> new Rules(){{
enemyCheat = true;

View File

@@ -28,5 +28,5 @@ public class Rules{
/**Zone ID, -1 for invalid zone.*/
public byte zone = -1;
/**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();
}

View File

@@ -137,7 +137,7 @@ public class MinimapRenderer implements Disposable{
private int colorFor(Tile tile){
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

View File

@@ -105,7 +105,7 @@ public class MapIO{
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); 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;

View File

@@ -13,7 +13,7 @@ import io.anuke.mindustry.io.MapIO;
import static io.anuke.mindustry.Vars.world;
public class Map{
public class Map implements Comparable<Map>{
/** Whether this is a custom map.*/
public final boolean custom;
/** Metadata. Author description, display name, etc.*/
@@ -54,10 +54,10 @@ public class Map{
}catch(Exception e){
Log.err("Malformed waves: {0}", tags.get("waves"));
e.printStackTrace();
return DefaultWaves.getDefaultSpawns();
return DefaultWaves.get();
}
}else{
return DefaultWaves.getDefaultSpawns();
return DefaultWaves.get();
}
}
@@ -90,6 +90,16 @@ public class Map{
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
public String toString(){
return "Map{" +

View File

@@ -113,6 +113,7 @@ public class Maps implements Disposable{
map.texture = new Texture(MapIO.generatePreview(data));
}
maps.add(map);
maps.sort();
}catch(IOException e){
throw new RuntimeException(e);
}
@@ -181,6 +182,7 @@ public class Maps implements Disposable{
}
maps.add(map);
maps.sort();
}
private void loadCustomMaps(){

View File

@@ -340,6 +340,6 @@ public class PlacementFragment extends Fragment{
/** Returns the block currently being hovered over in the world. */
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;
}
}

View 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
}
}

View File

@@ -345,7 +345,7 @@ public class Tile implements Position, TargetTrait{
this.ore = 0;
}
public Floor oreBlock(){
public Floor ore(){
return (Floor)content.block(ore);
}

View File

@@ -18,6 +18,11 @@ public class BlockPart extends Block{
hasPower = hasItems = hasLiquids = true;
}
@Override
public boolean synthetic(){
return true;
}
@Override
public boolean isHidden(){
return true;

View File

@@ -109,7 +109,7 @@ public class Floor extends Block{
Mathf.random.setSeed(tile.pos());
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
floor.draw(tile);
}