Implemented random map load filters
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,6 +21,7 @@ logs/
|
|||||||
/test_files/
|
/test_files/
|
||||||
/annotations/build/
|
/annotations/build/
|
||||||
/desktop-sdl/build/
|
/desktop-sdl/build/
|
||||||
|
desktop-sdl/build/
|
||||||
/android/assets/mindustry-maps/
|
/android/assets/mindustry-maps/
|
||||||
/android/assets/mindustry-saves/
|
/android/assets/mindustry-saves/
|
||||||
/core/assets/gifexport/
|
/core/assets/gifexport/
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ editor.author = Author:
|
|||||||
editor.description = Description:
|
editor.description = Description:
|
||||||
editor.waves = Waves:
|
editor.waves = Waves:
|
||||||
editor.rules = Rules:
|
editor.rules = Rules:
|
||||||
|
editor.generation = Generation:
|
||||||
editor.ingame = Edit In-Game
|
editor.ingame = Edit In-Game
|
||||||
editor.newmap = New Map
|
editor.newmap = New Map
|
||||||
waves.title = Waves
|
waves.title = Waves
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
import io.anuke.annotations.Annotations.Nullable;
|
import io.anuke.annotations.Annotations.*;
|
||||||
import io.anuke.arc.*;
|
import io.anuke.arc.*;
|
||||||
import io.anuke.arc.collection.IntArray;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.*;
|
||||||
import io.anuke.arc.math.geom.Point2;
|
|
||||||
import io.anuke.arc.util.*;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.ai.*;
|
import io.anuke.mindustry.ai.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.*;
|
||||||
import io.anuke.mindustry.entities.Entities;
|
import io.anuke.mindustry.editor.MapGenerateDialog.*;
|
||||||
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
import io.anuke.mindustry.entities.*;
|
||||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
import io.anuke.mindustry.game.EventType.*;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.io.MapIO;
|
import io.anuke.mindustry.io.*;
|
||||||
import io.anuke.mindustry.maps.*;
|
import io.anuke.mindustry.maps.*;
|
||||||
import io.anuke.mindustry.maps.generators.Generator;
|
import io.anuke.mindustry.maps.filters.*;
|
||||||
import io.anuke.mindustry.type.Zone;
|
import io.anuke.mindustry.maps.filters.GenerateFilter.*;
|
||||||
|
import io.anuke.mindustry.maps.generators.*;
|
||||||
|
import io.anuke.mindustry.type.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.BlockPart;
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -172,12 +173,6 @@ public class World implements ApplicationListener{
|
|||||||
generating = true;
|
generating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call to signal the beginning of loading the map with a custom set of tiles. */
|
|
||||||
public void beginMapLoad(Tile[][] tiles){
|
|
||||||
this.tiles = tiles;
|
|
||||||
generating = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call to signify the end of map loading. Updates tile occlusions and sets up physics for the world.
|
* Call to signify the end of map loading. Updates tile occlusions and sets up physics for the world.
|
||||||
* A WorldLoadEvent will be fire.
|
* A WorldLoadEvent will be fire.
|
||||||
@@ -226,9 +221,8 @@ public class World implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadMap(Map map){
|
public void loadMap(Map map){
|
||||||
|
|
||||||
try{
|
try{
|
||||||
MapIO.loadMap(map);
|
SaveIO.load(map.file, new FilterContext(map));
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
if(!headless){
|
if(!headless){
|
||||||
@@ -315,50 +309,6 @@ public class World implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Raycast, but with world coordinates.
|
|
||||||
*/
|
|
||||||
public Point2 raycastWorld(float x, float y, float x2, float y2){
|
|
||||||
return raycast(Math.round(x / tilesize), Math.round(y / tilesize),
|
|
||||||
Math.round(x2 / tilesize), Math.round(y2 / tilesize));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Input is in block coordinates, not world coordinates.
|
|
||||||
* @return null if no collisions found, block position otherwise.
|
|
||||||
*/
|
|
||||||
public Point2 raycast(int x0f, int y0f, int x1, int y1){
|
|
||||||
int x0 = x0f;
|
|
||||||
int y0 = y0f;
|
|
||||||
int dx = Math.abs(x1 - x0);
|
|
||||||
int dy = Math.abs(y1 - y0);
|
|
||||||
|
|
||||||
int sx = x0 < x1 ? 1 : -1;
|
|
||||||
int sy = y0 < y1 ? 1 : -1;
|
|
||||||
|
|
||||||
int err = dx - dy;
|
|
||||||
int e2;
|
|
||||||
while(true){
|
|
||||||
|
|
||||||
if(!passable(x0, y0)){
|
|
||||||
return Tmp.g1.set(x0, y0);
|
|
||||||
}
|
|
||||||
if(x0 == x1 && y0 == y1) break;
|
|
||||||
|
|
||||||
e2 = 2 * err;
|
|
||||||
if(e2 > -dy){
|
|
||||||
err = err - dy;
|
|
||||||
x0 = x0 + sx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e2 < dx){
|
|
||||||
err = err + dx;
|
|
||||||
y0 = y0 + sy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void raycastEachWorld(float x0, float y0, float x1, float y1, Raycaster cons){
|
public void raycastEachWorld(float x0, float y0, float x1, float y1, Raycaster cons){
|
||||||
raycastEach(toTile(x0), toTile(y0), toTile(x1), toTile(y1), cons);
|
raycastEach(toTile(x0), toTile(y0), toTile(x1), toTile(y1), cons);
|
||||||
}
|
}
|
||||||
@@ -489,7 +439,7 @@ public class World implements ApplicationListener{
|
|||||||
boolean accept(int x, int y);
|
boolean accept(int x, int y);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Context implements WorldContext{
|
private class Context implements WorldContext{
|
||||||
@Override
|
@Override
|
||||||
public Tile tile(int x, int y){
|
public Tile tile(int x, int y){
|
||||||
return tiles[x][y];
|
return tiles[x][y];
|
||||||
@@ -520,4 +470,45 @@ public class World implements ApplicationListener{
|
|||||||
endMapLoad();
|
endMapLoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** World context that applies filters after generation end. */
|
||||||
|
private class FilterContext extends Context{
|
||||||
|
final Map map;
|
||||||
|
|
||||||
|
FilterContext(Map map){
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void end(){
|
||||||
|
Array<GenerateFilter> filters = map.filters();
|
||||||
|
if(!filters.isEmpty()){
|
||||||
|
//input for filter queries
|
||||||
|
GenerateInput input = new GenerateInput();
|
||||||
|
GenTile gtile = new GenTile();
|
||||||
|
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
input.begin(filter, width(), height(), (x, y) -> gtile.set(tiles[x][y]));
|
||||||
|
|
||||||
|
//actually apply the filter
|
||||||
|
for(int x = 0; x < width(); x++){
|
||||||
|
for(int y = 0; y < height(); y++){
|
||||||
|
Tile tile = rawTile(x, y);
|
||||||
|
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
|
||||||
|
filter.apply(input);
|
||||||
|
|
||||||
|
tile.setFloor((Floor)input.floor);
|
||||||
|
tile.setOverlay(input.ore);
|
||||||
|
|
||||||
|
if(!tile.block().synthetic()){
|
||||||
|
tile.setBlock(input.block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ 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);
|
generateDialog = new MapGenerateDialog(editor, true);
|
||||||
|
|
||||||
menu = new FloatingDialog("$menu");
|
menu = new FloatingDialog("$menu");
|
||||||
menu.addCloseButton();
|
menu.addCloseButton();
|
||||||
@@ -81,7 +81,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
t.row();
|
t.row();
|
||||||
|
|
||||||
t.addImageTextButton("$editor.generate", "icon-editor", isize, () -> {
|
t.addImageTextButton("$editor.generate", "icon-editor", isize, () -> {
|
||||||
generateDialog.show();
|
generateDialog.show(generateDialog::applyToEditor);
|
||||||
menu.hide();
|
menu.hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
MirrorFilter::new
|
MirrorFilter::new
|
||||||
};
|
};
|
||||||
private final MapEditor editor;
|
private final MapEditor editor;
|
||||||
|
private final boolean applied;
|
||||||
|
|
||||||
private Pixmap pixmap;
|
private Pixmap pixmap;
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
@@ -46,19 +47,24 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
private GenTile returnTile = new GenTile();
|
private GenTile returnTile = new GenTile();
|
||||||
|
|
||||||
private GenTile[][] buffer1, buffer2;
|
private GenTile[][] buffer1, buffer2;
|
||||||
|
private Consumer<Array<GenerateFilter>> applier;
|
||||||
|
|
||||||
public MapGenerateDialog(MapEditor editor){
|
/** @param applied whether or not to use the applied in-game mode. */
|
||||||
|
public MapGenerateDialog(MapEditor editor, boolean applied){
|
||||||
super("$editor.generate");
|
super("$editor.generate");
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
this.applied = applied;
|
||||||
|
|
||||||
shown(this::setup);
|
shown(this::setup);
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
buttons.addButton("$editor.apply", () -> {
|
if(applied){
|
||||||
ui.loadAnd(() -> {
|
buttons.addButton("$editor.apply", () -> {
|
||||||
apply();
|
ui.loadAnd(() -> {
|
||||||
hide();
|
apply();
|
||||||
});
|
hide();
|
||||||
}).size(160f, 64f);
|
});
|
||||||
|
}).size(160f, 64f);
|
||||||
|
}
|
||||||
buttons.addButton("$editor.randomize", () -> {
|
buttons.addButton("$editor.randomize", () -> {
|
||||||
for(GenerateFilter filter : filters){
|
for(GenerateFilter filter : filters){
|
||||||
filter.randomize();
|
filter.randomize();
|
||||||
@@ -67,6 +73,76 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
}).size(160f, 64f);
|
}).size(160f, 64f);
|
||||||
|
|
||||||
buttons.addImageTextButton("$add", "icon-add", iconsize, this::showAdd).height(64f).width(140f);
|
buttons.addImageTextButton("$add", "icon-add", iconsize, this::showAdd).height(64f).width(140f);
|
||||||
|
|
||||||
|
if(!applied){
|
||||||
|
hidden(this::apply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(Array<GenerateFilter> filters, Consumer<Array<GenerateFilter>> applier){
|
||||||
|
this.filters = filters;
|
||||||
|
this.applier = applier;
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(Consumer<Array<GenerateFilter>> applier){
|
||||||
|
show(this.filters, applier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Applies the specified filters to the editor. */
|
||||||
|
public void applyToEditor(Array<GenerateFilter> filters){
|
||||||
|
//writeback buffer
|
||||||
|
GenTile[][] writeTiles = new GenTile[editor.width()][editor.height()];
|
||||||
|
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
writeTiles[x][y] = new GenTile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(GenerateFilter filter : filters){
|
||||||
|
input.begin(filter, editor.width(), editor.height(), (x, y) -> dset(editor.tile(x, y)));
|
||||||
|
//write to buffer
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
|
||||||
|
filter.apply(input);
|
||||||
|
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.load(() -> {
|
||||||
|
//read from buffer back into tiles
|
||||||
|
for(int x = 0; x < editor.width(); x++){
|
||||||
|
for(int y = 0; y < editor.height(); y++){
|
||||||
|
Tile tile = editor.tile(x, y);
|
||||||
|
GenTile write = writeTiles[x][y];
|
||||||
|
|
||||||
|
tile.rotation(write.rotation);
|
||||||
|
tile.setFloor((Floor)content.block(write.floor));
|
||||||
|
tile.setBlock(content.block(write.block));
|
||||||
|
tile.setTeam(Team.all[write.team]);
|
||||||
|
tile.setOverlay(content.block(write.ore));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//reset undo stack as generation... messes things up
|
||||||
|
editor.load(editor::checkLinkedTiles);
|
||||||
|
editor.renderer().updateAll();
|
||||||
|
editor.clearOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDefaultOres(Array<GenerateFilter> filters){
|
||||||
|
int index = 0;
|
||||||
|
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreCoal, Blocks.oreLead, Blocks.oreTitanium, Blocks.oreThorium}){
|
||||||
|
OreFilter filter = new OreFilter();
|
||||||
|
filter.threshold += index ++ * 0.025f;
|
||||||
|
filter.ore = block;
|
||||||
|
filters.add(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
@@ -140,6 +216,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
filterTable.top();
|
filterTable.top();
|
||||||
|
|
||||||
for(GenerateFilter filter : filters){
|
for(GenerateFilter filter : filters){
|
||||||
|
|
||||||
//main container
|
//main container
|
||||||
filterTable.table("button", c -> {
|
filterTable.table("button", c -> {
|
||||||
//icons to perform actions
|
//icons to perform actions
|
||||||
@@ -206,6 +283,9 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for(Supplier<GenerateFilter> gen : filterTypes){
|
for(Supplier<GenerateFilter> gen : filterTypes){
|
||||||
GenerateFilter filter = gen.get();
|
GenerateFilter filter = gen.get();
|
||||||
|
|
||||||
|
if(!applied && filter.buffered) continue;
|
||||||
|
|
||||||
selection.cont.addButton(filter.name(), () -> {
|
selection.cont.addButton(filter.name(), () -> {
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
rebuildFilters();
|
rebuildFilters();
|
||||||
@@ -216,14 +296,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
selection.cont.addButton("Default Ores", () -> {
|
selection.cont.addButton("Default Ores", () -> {
|
||||||
int index = 0;
|
addDefaultOres(filters);
|
||||||
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreCoal, Blocks.oreLead, Blocks.oreTitanium, Blocks.oreThorium}){
|
|
||||||
OreFilter filter = new OreFilter();
|
|
||||||
filter.threshold += index ++ * 0.02f;
|
|
||||||
filter.ore = block;
|
|
||||||
filters.add(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildFilters();
|
rebuildFilters();
|
||||||
update();
|
update();
|
||||||
selection.hide();
|
selection.hide();
|
||||||
@@ -253,48 +326,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
texture = null;
|
texture = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//writeback buffer
|
applier.accept(filters);
|
||||||
GenTile[][] writeTiles = new GenTile[editor.width()][editor.height()];
|
|
||||||
|
|
||||||
for(int x = 0; x < editor.width(); x++){
|
|
||||||
for(int y = 0; y < editor.height(); y++){
|
|
||||||
writeTiles[x][y] = new GenTile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(GenerateFilter filter : filters){
|
|
||||||
input.begin(filter, editor.width(), editor.height(), (x, y) -> dset(editor.tile(x, y)));
|
|
||||||
//write to buffer
|
|
||||||
for(int x = 0; x < editor.width(); x++){
|
|
||||||
for(int y = 0; y < editor.height(); y++){
|
|
||||||
Tile tile = editor.tile(x, y);
|
|
||||||
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
|
|
||||||
filter.apply(input);
|
|
||||||
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.load(() -> {
|
|
||||||
//read from buffer back into tiles
|
|
||||||
for(int x = 0; x < editor.width(); x++){
|
|
||||||
for(int y = 0; y < editor.height(); y++){
|
|
||||||
Tile tile = editor.tile(x, y);
|
|
||||||
GenTile write = writeTiles[x][y];
|
|
||||||
|
|
||||||
tile.rotation(write.rotation);
|
|
||||||
tile.setFloor((Floor)content.block(write.floor));
|
|
||||||
tile.setBlock(content.block(write.block));
|
|
||||||
tile.setTeam(Team.all[write.team]);
|
|
||||||
tile.setOverlay(content.block(write.ore));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//reset undo stack as generation... messes things up
|
|
||||||
editor.load(editor::checkLinkedTiles);
|
|
||||||
editor.renderer().updateAll();
|
|
||||||
editor.clearOp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(){
|
void update(){
|
||||||
@@ -371,7 +403,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
public byte team, rotation;
|
public byte team, rotation;
|
||||||
public short block, floor, ore;
|
public short block, floor, ore;
|
||||||
|
|
||||||
void set(Block floor, Block wall, Block ore, Team team, int rotation){
|
public void set(Block floor, Block wall, Block ore, Team team, int rotation){
|
||||||
this.floor = floor.id;
|
this.floor = floor.id;
|
||||||
this.block = wall.id;
|
this.block = wall.id;
|
||||||
this.ore = ore.id;
|
this.ore = ore.id;
|
||||||
@@ -379,7 +411,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
this.rotation = (byte)rotation;
|
this.rotation = (byte)rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(GenTile other){
|
public 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;
|
||||||
@@ -387,8 +419,9 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
this.rotation = other.rotation;
|
this.rotation = other.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(Tile other){
|
public GenTile set(Tile other){
|
||||||
set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation());
|
set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation());
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
package io.anuke.mindustry.editor;
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.*;
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.scene.ui.TextArea;
|
import io.anuke.arc.scene.ui.*;
|
||||||
import io.anuke.arc.scene.ui.TextField;
|
import io.anuke.mindustry.*;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.core.*;
|
||||||
import io.anuke.mindustry.core.Platform;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.game.Rules;
|
import io.anuke.mindustry.io.*;
|
||||||
import io.anuke.mindustry.ui.dialogs.CustomRulesDialog;
|
import io.anuke.mindustry.ui.dialogs.*;
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
|
||||||
|
|
||||||
public class MapInfoDialog extends FloatingDialog{
|
public class MapInfoDialog extends FloatingDialog{
|
||||||
private final MapEditor editor;
|
private final MapEditor editor;
|
||||||
private final WaveInfoDialog waveInfo;
|
private final WaveInfoDialog waveInfo;
|
||||||
|
private final MapGenerateDialog generate;
|
||||||
private final CustomRulesDialog ruleInfo = new CustomRulesDialog();
|
private final CustomRulesDialog ruleInfo = new CustomRulesDialog();
|
||||||
|
|
||||||
public MapInfoDialog(MapEditor editor){
|
public MapInfoDialog(MapEditor editor){
|
||||||
super("$editor.mapinfo");
|
super("$editor.mapinfo");
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
this.waveInfo = new WaveInfoDialog(editor);
|
this.waveInfo = new WaveInfoDialog(editor);
|
||||||
|
this.generate = new MapGenerateDialog(editor, false);
|
||||||
|
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
|
|
||||||
@@ -64,6 +65,13 @@ public class MapInfoDialog extends FloatingDialog{
|
|||||||
t.add("$editor.waves").padRight(8).left();
|
t.add("$editor.waves").padRight(8).left();
|
||||||
t.addButton("$edit", waveInfo::show).left().width(200f);
|
t.addButton("$edit", waveInfo::show).left().width(200f);
|
||||||
|
|
||||||
|
t.row();
|
||||||
|
t.add("$editor.generation").padRight(8).left();
|
||||||
|
t.addButton("$edit",
|
||||||
|
() -> generate.show(JsonIO.read(Array.class, editor.getTags().get("genfilters", "{}")),
|
||||||
|
filters -> editor.getTags().put("genfilters", JsonIO.write(filters)))
|
||||||
|
).left().width(200f);
|
||||||
|
|
||||||
name.change();
|
name.change();
|
||||||
description.change();
|
description.change();
|
||||||
author.change();
|
author.change();
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package io.anuke.mindustry.io;
|
|||||||
|
|
||||||
import io.anuke.arc.collection.EnumSet;
|
import io.anuke.arc.collection.EnumSet;
|
||||||
import io.anuke.arc.collection.LongQueue;
|
import io.anuke.arc.collection.LongQueue;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.arc.util.serialization.Json;
|
import io.anuke.arc.util.serialization.Json;
|
||||||
import io.anuke.arc.util.serialization.JsonValue;
|
import io.anuke.arc.util.serialization.JsonValue;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.game.*;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.game.Teams.TeamData;
|
import io.anuke.mindustry.game.Teams.TeamData;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class JsonIO{
|
public class JsonIO{
|
||||||
@@ -40,6 +42,37 @@ public class JsonIO{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TODO extremely hacky and disgusting
|
||||||
|
for(Block block : Vars.content.blocks()){
|
||||||
|
Class type = block.getClass();
|
||||||
|
if(type.isAnonymousClass()) type = type.getSuperclass();
|
||||||
|
Log.info(type);
|
||||||
|
|
||||||
|
setSerializer(type, new Serializer<Block>(){
|
||||||
|
@Override
|
||||||
|
public void write(Json json, Block object, Class knownType){
|
||||||
|
json.writeValue(object.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block read(Json json, JsonValue jsonData, Class type){
|
||||||
|
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setSerializer(Block.class, new Serializer<Block>(){
|
||||||
|
@Override
|
||||||
|
public void write(Json json, Block object, Class knownType){
|
||||||
|
json.writeValue(object.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block read(Json json, JsonValue jsonData, Class type){
|
||||||
|
return Vars.content.getByName(ContentType.block, jsonData.asString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setSerializer(TeamData.class, new Serializer<TeamData>(){
|
setSerializer(TeamData.class, new Serializer<TeamData>(){
|
||||||
@Override
|
@Override
|
||||||
public void write(Json json, TeamData object, Class knownType){
|
public void write(Json json, TeamData object, Class knownType){
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.anuke.arc.graphics.Texture;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.game.*;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.io.JsonIO;
|
import io.anuke.mindustry.io.JsonIO;
|
||||||
|
import io.anuke.mindustry.maps.filters.*;
|
||||||
|
|
||||||
public class Map implements Comparable<Map>{
|
public class Map implements Comparable<Map>{
|
||||||
/** Whether this is a custom map. */
|
/** Whether this is a custom map. */
|
||||||
@@ -59,25 +60,18 @@ public class Map implements Comparable<Map>{
|
|||||||
Vars.data.modified();
|
Vars.data.modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This creates a new instance.*/
|
/** This creates a new instance of Rules.*/
|
||||||
public Rules rules(){
|
public Rules rules(){
|
||||||
Rules result = JsonIO.read(Rules.class, tags.get("rules", "{}"));
|
Rules result = JsonIO.read(Rules.class, tags.get("rules", "{}"));
|
||||||
if(result.spawns.isEmpty()) result.spawns = Vars.defaultWaves.get();
|
if(result.spawns.isEmpty()) result.spawns = Vars.defaultWaves.get();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this map has a core of the enemy 'wave' team. Default: true.
|
/** Returns the generation filters that this map uses on load.*/
|
||||||
* Used for checking Attack mode validity.
|
public Array<GenerateFilter> filters(){
|
||||||
public boolean hasEnemyCore(){
|
return JsonIO.read(Array.class, tags.get("genfilters", "{}"));
|
||||||
return tags.get("enemycore", "true").equals("true");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this map has a core of any team except the default player team. Default: true.
|
|
||||||
* Used for checking PvP mode validity.
|
|
||||||
public boolean hasOtherCores(){
|
|
||||||
return tags.get("othercore", "true").equals("true");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public String author(){
|
public String author(){
|
||||||
return tag("author");
|
return tag("author");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class BlendFilter extends GenerateFilter{
|
|||||||
Block flooronto = Blocks.stone, floor = Blocks.ice;
|
Block flooronto = Blocks.stone, floor = Blocks.ice;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
buffered = true;
|
||||||
options(
|
options(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
||||||
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOnly),
|
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOnly),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class DistortFilter extends GenerateFilter{
|
|||||||
float scl = 40, mag = 5;
|
float scl = 40, mag = 5;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
buffered = true;
|
||||||
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)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public abstract class GenerateFilter{
|
|||||||
protected transient long seed;
|
protected transient long seed;
|
||||||
protected transient GenerateInput in;
|
protected transient GenerateInput in;
|
||||||
|
|
||||||
public FilterOption[] options;
|
public transient boolean buffered = false;
|
||||||
|
public transient FilterOption[] options;
|
||||||
|
|
||||||
public final void apply(GenerateInput in){
|
public final void apply(GenerateInput in){
|
||||||
this.in = in;
|
this.in = in;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class MedianFilter extends GenerateFilter{
|
|||||||
IntArray blocks = new IntArray(), floors = new IntArray();
|
IntArray blocks = new IntArray(), floors = new IntArray();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
buffered = true;
|
||||||
options(
|
options(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
||||||
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import static io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
|||||||
import static io.anuke.mindustry.maps.filters.FilterOption.oresOnly;
|
import static io.anuke.mindustry.maps.filters.FilterOption.oresOnly;
|
||||||
|
|
||||||
public class OreFilter extends GenerateFilter{
|
public class OreFilter extends GenerateFilter{
|
||||||
public float scl = 50, threshold = 0.72f, octaves = 3f, falloff = 0.4f;
|
public float scl = 45, threshold = 0.73f, octaves = 3f, falloff = 0.4f;
|
||||||
public Block ore = Blocks.oreCopper;
|
public Block ore = Blocks.oreCopper;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
package io.anuke.mindustry.maps.generators;
|
package io.anuke.mindustry.maps.generators;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.Point2;
|
import io.anuke.arc.math.geom.*;
|
||||||
import io.anuke.arc.util.Structs;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.arc.util.noise.Simplex;
|
import io.anuke.arc.util.noise.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.io.MapIO;
|
import io.anuke.mindustry.io.*;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.*;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.*;
|
||||||
import io.anuke.mindustry.type.Loadout;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
import io.anuke.mindustry.world.blocks.storage.*;
|
||||||
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.defaultTeam;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class MapGenerator extends Generator{
|
public class MapGenerator extends Generator{
|
||||||
private Map map;
|
private Map map;
|
||||||
@@ -82,7 +78,7 @@ public class MapGenerator extends Generator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapIO.loadMap(map);
|
SaveIO.load(map.file);
|
||||||
Array<Point2> players = new Array<>();
|
Array<Point2> players = new Array<>();
|
||||||
Array<Point2> enemies = new Array<>();
|
Array<Point2> enemies = new Array<>();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user