Refactoring of tile storage, filters
This commit is contained in:
@@ -9,6 +9,8 @@ public class Planets implements ContentList{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
|
starter = new Planet("//TODO"){{
|
||||||
|
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class Zones implements ContentList{
|
|||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
|
|
||||||
groundZero = new Zone("groundZero", starter, new MapGenerator("groundZero", 1)){{
|
groundZero = new Zone("groundZero", starter, new MapGenerator("groundZero")){{
|
||||||
baseLaunchCost = list(copper, -60);
|
baseLaunchCost = list(copper, -60);
|
||||||
startingItems = list(copper, 60);
|
startingItems = list(copper, 60);
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
@@ -98,8 +98,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
frozenForest = new Zone("frozenForest", starter, new MapGenerator("frozenForest", 1)
|
frozenForest = new Zone("frozenForest", starter, new MapGenerator("frozenForest")){{
|
||||||
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 250);
|
startingItems = list(copper, 250);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
@@ -111,7 +110,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
craters = new Zone("craters", starter, new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
|
craters = new Zone("craters", starter, new MapGenerator("craters")){{
|
||||||
startingItems = list(copper, 100);
|
startingItems = list(copper, 100);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
resources = with(copper, lead, coal, sand, scrap);
|
resources = with(copper, lead, coal, sand, scrap);
|
||||||
@@ -122,7 +121,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ruinousShores = new Zone("ruinousShores", starter, new MapGenerator("ruinousShores", 1)){{
|
ruinousShores = new Zone("ruinousShores", starter, new MapGenerator("ruinousShores")){{
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 140, lead, 50);
|
startingItems = list(copper, 140, lead, 50);
|
||||||
conditionWave = 20;
|
conditionWave = 20;
|
||||||
@@ -138,8 +137,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
stainedMountains = new Zone("stainedMountains", starter, new MapGenerator("stainedMountains", 2)
|
stainedMountains = new Zone("stainedMountains", starter, new MapGenerator("stainedMountains")){{
|
||||||
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 200, lead, 50);
|
startingItems = list(copper, 200, lead, 50);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
@@ -183,8 +181,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
tarFields = new Zone("tarFields", starter, new MapGenerator("tarFields")
|
tarFields = new Zone("tarFields", starter, new MapGenerator("tarFields")){{
|
||||||
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 250, lead, 100);
|
startingItems = list(copper, 250, lead, 100);
|
||||||
conditionWave = 15;
|
conditionWave = 15;
|
||||||
@@ -223,8 +220,7 @@ public class Zones implements ContentList{
|
|||||||
resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
||||||
}};*/
|
}};*/
|
||||||
|
|
||||||
nuclearComplex = new Zone("nuclearComplex", starter, new MapGenerator("nuclearProductionComplex", 1)
|
nuclearComplex = new Zone("nuclearComplex", starter, new MapGenerator("nuclearProductionComplex")){{
|
||||||
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{
|
|
||||||
loadout = Loadouts.basicNucleus;
|
loadout = Loadouts.basicNucleus;
|
||||||
startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
|
startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
|
||||||
conditionWave = 30;
|
conditionWave = 30;
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ public class ContentLoader{
|
|||||||
new Blocks(),
|
new Blocks(),
|
||||||
new Loadouts(),
|
new Loadouts(),
|
||||||
new TechTree(),
|
new TechTree(),
|
||||||
|
new Weathers(),
|
||||||
|
new Planets(),
|
||||||
new Zones(),
|
new Zones(),
|
||||||
new TypeIDs(),
|
new TypeIDs(),
|
||||||
|
|
||||||
|
|||||||
@@ -276,8 +276,8 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
|
|
||||||
world.createTiles(zone.generator.width, zone.generator.height);
|
world.resize(zone.generator.width, zone.generator.height);
|
||||||
zone.generator.generate(world.getTiles());
|
zone.generator.generate(world.tiles);
|
||||||
|
|
||||||
Tile coreb = null;
|
Tile coreb = null;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import io.anuke.arc.*;
|
|||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.*;
|
import io.anuke.arc.math.geom.*;
|
||||||
import io.anuke.arc.util.*;
|
|
||||||
import io.anuke.arc.util.ArcAnnotate.*;
|
import io.anuke.arc.util.ArcAnnotate.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.core.GameState.*;
|
import io.anuke.mindustry.core.GameState.*;
|
||||||
import io.anuke.mindustry.game.EventType.*;
|
import io.anuke.mindustry.game.EventType.*;
|
||||||
@@ -25,7 +25,7 @@ public class World{
|
|||||||
public final Context context = new Context();
|
public final Context context = new Context();
|
||||||
|
|
||||||
private Map currentMap;
|
private Map currentMap;
|
||||||
private Tile[][] tiles;
|
public @NonNull Tiles tiles = new Tiles(0, 0);
|
||||||
|
|
||||||
private boolean generating, invalidMap;
|
private boolean generating, invalidMap;
|
||||||
|
|
||||||
@@ -67,11 +67,11 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int width(){
|
public int width(){
|
||||||
return tiles == null ? 0 : tiles.length;
|
return tiles.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int height(){
|
public int height(){
|
||||||
return tiles == null ? 0 : tiles[0].length;
|
return tiles.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int unitWidth(){
|
public int unitWidth(){
|
||||||
@@ -88,11 +88,7 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile tile(int x, int y){
|
public @Nullable Tile tile(int x, int y){
|
||||||
if(tiles == null){
|
return tiles.get(x, y);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if(!Structs.inBounds(x, y, tiles)) return null;
|
|
||||||
return tiles[x][y];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile ltile(int x, int y){
|
public @Nullable Tile ltile(int x, int y){
|
||||||
@@ -102,7 +98,7 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tile rawTile(int x, int y){
|
public Tile rawTile(int x, int y){
|
||||||
return tiles[x][y];
|
return tiles.getn(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile tileWorld(float x, float y){
|
public @Nullable Tile tileWorld(float x, float y){
|
||||||
@@ -117,16 +113,10 @@ public class World{
|
|||||||
return Math.round(coord / tilesize);
|
return Math.round(coord / tilesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[][] getTiles(){
|
|
||||||
return tiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTileEntities(){
|
private void clearTileEntities(){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
if(tile != null && tile.entity != null){
|
||||||
if(tiles[x][y] != null && tiles[x][y].entity != null){
|
tile.entity.remove();
|
||||||
tiles[x][y].entity.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,15 +125,11 @@ public class World{
|
|||||||
* Resizes the tile array to the specified size and returns the resulting tile array.
|
* Resizes the tile array to the specified size and returns the resulting tile array.
|
||||||
* Only use for loading saves!
|
* Only use for loading saves!
|
||||||
*/
|
*/
|
||||||
public Tile[][] createTiles(int width, int height){
|
public Tiles resize(int width, int height){
|
||||||
if(tiles != null){
|
clearTileEntities();
|
||||||
clearTileEntities();
|
|
||||||
|
|
||||||
if(tiles.length != width || tiles[0].length != height){
|
if(tiles.width() != width || tiles.height() != height){
|
||||||
tiles = new Tile[width][height];
|
tiles = new Tiles(width, height);
|
||||||
}
|
|
||||||
}else{
|
|
||||||
tiles = new Tile[width][height];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tiles;
|
return tiles;
|
||||||
@@ -164,14 +150,11 @@ public class World{
|
|||||||
public void endMapLoad(){
|
public void endMapLoad(){
|
||||||
prepareTiles(tiles);
|
prepareTiles(tiles);
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
tile.updateOcclusion();
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
tile.updateOcclusion();
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.entity != null){
|
||||||
tile.entity.updateProximity();
|
tile.entity.updateProximity();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +162,7 @@ public class World{
|
|||||||
addDarkness(tiles);
|
addDarkness(tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2));
|
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2));
|
||||||
|
|
||||||
generating = false;
|
generating = false;
|
||||||
Events.fire(new WorldLoadEvent());
|
Events.fire(new WorldLoadEvent());
|
||||||
@@ -204,7 +187,7 @@ public class World{
|
|||||||
public void loadGenerator(Generator generator){
|
public void loadGenerator(Generator generator){
|
||||||
beginMapLoad();
|
beginMapLoad();
|
||||||
|
|
||||||
createTiles(generator.width, generator.height);
|
resize(generator.width, generator.height);
|
||||||
generator.generate(tiles);
|
generator.generate(tiles);
|
||||||
|
|
||||||
endMapLoad();
|
endMapLoad();
|
||||||
@@ -338,58 +321,56 @@ public class World{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDarkness(Tile[][] tiles){
|
public void addDarkness(Tiles tiles){
|
||||||
byte[][] dark = new byte[tiles.length][tiles[0].length];
|
byte[] dark = new byte[tiles.width() * tiles.height()];
|
||||||
byte[][] writeBuffer = new byte[tiles.length][tiles[0].length];
|
byte[] writeBuffer = new byte[tiles.width() * tiles.height()];
|
||||||
|
|
||||||
byte darkIterations = 4;
|
byte darkIterations = 4;
|
||||||
for(int x = 0; x < tiles.length; x++){
|
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
for(int i = 0; i < dark.length; i++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.geti(i);
|
||||||
if(tile.isDarkened()){
|
if(tile.isDarkened()){
|
||||||
dark[x][y] = darkIterations;
|
dark[i] = darkIterations;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < darkIterations; i++){
|
for(int i = 0; i < darkIterations; i++){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
int idx = tile.y * tiles.width() + tile.x;
|
||||||
boolean min = false;
|
boolean min = false;
|
||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newX = x + point.x, newY = y + point.y;
|
int newX = tile.x + point.x, newY = tile.y + point.y;
|
||||||
if(Structs.inBounds(newX, newY, tiles) && dark[newX][newY] < dark[x][y]){
|
int nidx = newY * tiles.width() + newX;
|
||||||
min = true;
|
if(tiles.in(newX, newY) && dark[nidx] < dark[idx]){
|
||||||
break;
|
min = true;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
writeBuffer[x][y] = (byte)Math.max(0, dark[x][y] - Mathf.num(min));
|
|
||||||
}
|
}
|
||||||
|
writeBuffer[idx] = (byte)Math.max(0, dark[idx] - Mathf.num(min));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
System.arraycopy(writeBuffer, 0, dark, 0, writeBuffer.length);
|
||||||
System.arraycopy(writeBuffer[x], 0, dark[x], 0, tiles[0].length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
int idx = tile.y * tiles.width() + tile.x;
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
if(tile.isDarkened()){
|
|
||||||
tiles[x][y].rotation(dark[x][y]);
|
|
||||||
}
|
|
||||||
if(dark[x][y] == 4){
|
|
||||||
boolean full = true;
|
|
||||||
for(Point2 p : Geometry.d4){
|
|
||||||
int px = p.x + x, py = p.y + y;
|
|
||||||
if(Structs.inBounds(px, py, tiles) && !(tiles[px][py].isDarkened() && dark[px][py] == 4)){
|
|
||||||
full = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(full) tiles[x][y].rotation(5);
|
if(tile.isDarkened()){
|
||||||
|
tile.rotation(dark[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dark[idx] == 4){
|
||||||
|
boolean full = true;
|
||||||
|
for(Point2 p : Geometry.d4){
|
||||||
|
int px = p.x + tile.x, py = p.y + tile.y;
|
||||||
|
int nidx = py * tiles.width() + px;
|
||||||
|
if(tiles.in(px, py) && !(tile.isDarkened() && dark[nidx] == 4)){
|
||||||
|
full = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(full) tile.rotation(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,18 +381,13 @@ public class World{
|
|||||||
* - updating occlusion<br>
|
* - updating occlusion<br>
|
||||||
* Usually used before placing structures on a tile array.
|
* Usually used before placing structures on a tile array.
|
||||||
*/
|
*/
|
||||||
public void prepareTiles(Tile[][] tiles){
|
public void prepareTiles(Tiles tiles){
|
||||||
|
|
||||||
//find multiblocks
|
//find multiblocks
|
||||||
IntArray multiblocks = new IntArray();
|
IntArray multiblocks = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
if(tile.block().isMultiblock()){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
multiblocks.add(tile.pos());
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
|
|
||||||
if(tile.block().isMultiblock()){
|
|
||||||
multiblocks.add(tile.pos());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,9 +397,10 @@ public class World{
|
|||||||
|
|
||||||
int x = Pos.x(pos);
|
int x = Pos.x(pos);
|
||||||
int y = Pos.y(pos);
|
int y = Pos.y(pos);
|
||||||
|
Tile tile = tiles.getn(x, y);
|
||||||
|
|
||||||
Block result = tiles[x][y].block();
|
Block result = tile.block();
|
||||||
Team team = tiles[x][y].getTeam();
|
Team team = tile.getTeam();
|
||||||
|
|
||||||
int offsetx = -(result.size - 1) / 2;
|
int offsetx = -(result.size - 1) / 2;
|
||||||
int offsety = -(result.size - 1) / 2;
|
int offsety = -(result.size - 1) / 2;
|
||||||
@@ -450,17 +427,19 @@ public class World{
|
|||||||
private 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.get(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
createTiles(width, height);
|
World.this.resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
||||||
return (tiles[x][y] = new Tile(x, y, floorID, overlayID, wallID));
|
Tile tile = new Tile(x, y, floorID, overlayID, wallID);
|
||||||
|
tiles.set(x, y, tile);
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -495,23 +474,8 @@ public class World{
|
|||||||
GenerateInput input = new GenerateInput();
|
GenerateInput input = new GenerateInput();
|
||||||
|
|
||||||
for(GenerateFilter filter : filters){
|
for(GenerateFilter filter : filters){
|
||||||
input.begin(filter, width(), height(), (x, y) -> tiles[x][y]);
|
input.begin(filter, width(), height(), (x, y) -> tiles.getn(x, y));
|
||||||
|
filter.apply(tiles, input);
|
||||||
//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() && !input.block.synthetic()){
|
|
||||||
tile.setBlock(input.block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,25 +70,23 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//adds missing blockparts
|
//adds missing blockparts
|
||||||
|
//TODO remove, may not be necessary with blockpart refactor later
|
||||||
public void checkLinkedTiles(){
|
public void checkLinkedTiles(){
|
||||||
Tile[][] tiles = world.getTiles();
|
Tiles tiles = world.tiles;
|
||||||
|
|
||||||
//clear block parts first
|
//clear old parts
|
||||||
for(int x = 0; x < width(); x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height(); y++){
|
if(tile.block() instanceof BlockPart){
|
||||||
if(tiles[x][y].block() instanceof BlockPart){
|
tile.setBlock(Blocks.air);
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up missing blockparts
|
//re-add them
|
||||||
for(int x = 0; x < width(); x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height(); y++){
|
if(tile.block().isMultiblock()){
|
||||||
if(tiles[x][y].block().isMultiblock()){
|
world.setBlock(tile, tile.block(), tile.getTeam());
|
||||||
world.setBlock(tiles[x][y], tiles[x][y].block(), tiles[x][y].getTeam());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,11 +98,11 @@ public class MapEditor{
|
|||||||
|
|
||||||
/** Creates a 2-D array of EditorTiles with stone as the floor block. */
|
/** Creates a 2-D array of EditorTiles with stone as the floor block. */
|
||||||
private void createTiles(int width, int height){
|
private void createTiles(int width, int height){
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
|
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,8 +118,8 @@ public class MapEditor{
|
|||||||
tags = new StringMap();
|
tags = new StringMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[][] tiles(){
|
public Tiles tiles(){
|
||||||
return world.getTiles();
|
return world.tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile tile(int x, int y){
|
public Tile tile(int x, int y){
|
||||||
@@ -246,20 +244,20 @@ public class MapEditor{
|
|||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
clearOp();
|
clearOp();
|
||||||
|
|
||||||
Tile[][] previous = world.getTiles();
|
Tiles previous = world.tiles;
|
||||||
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
|
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
int px = offsetX + x, py = offsetY + y;
|
int px = offsetX + x, py = offsetY + y;
|
||||||
if(Structs.inBounds(px, py, previous.length, previous[0].length)){
|
if(previous.in(px, py)){
|
||||||
tiles[x][y] = previous[px][py];
|
tiles.set(x, y, previous.getn(px, py));
|
||||||
tiles[x][y].x = (short)x;
|
tiles.getn(x, y).x = (short)x;
|
||||||
tiles[x][y].y = (short)y;
|
tiles.getn(x, y).y = (short)y;
|
||||||
}else{
|
}else{
|
||||||
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
|
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,12 +313,14 @@ public class MapEditor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
world.createTiles(width, height);
|
world.resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
||||||
return (tiles()[x][y] = new EditorTile(x, y, floorID, overlayID, wallID));
|
Tile tile = new EditorTile(x, y, floorID, overlayID, wallID);
|
||||||
|
tiles().set(x, y, tile);
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
//all the options
|
//all the options
|
||||||
c.table(f -> {
|
c.table(f -> {
|
||||||
f.left().top();
|
f.left().top();
|
||||||
for(FilterOption option : filter.options){
|
for(FilterOption option : filter.options()){
|
||||||
option.changed = this::update;
|
option.changed = this::update;
|
||||||
|
|
||||||
f.table(t -> {
|
f.table(t -> {
|
||||||
@@ -292,7 +292,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
for(Prov<GenerateFilter> gen : filterTypes){
|
for(Prov<GenerateFilter> gen : filterTypes){
|
||||||
GenerateFilter filter = gen.get();
|
GenerateFilter filter = gen.get();
|
||||||
|
|
||||||
if(!applied && filter.buffered) continue;
|
if(!applied && filter.isBuffered()) continue;
|
||||||
|
|
||||||
selection.cont.addButton(filter.name(), () -> {
|
selection.cont.addButton(filter.name(), () -> {
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
@@ -360,21 +360,17 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
|
|
||||||
for(GenerateFilter filter : copy){
|
for(GenerateFilter filter : copy){
|
||||||
input.begin(filter, editor.width(), editor.height(), (x, y) -> buffer1[Mathf.clamp(x / scaling, 0, pixmap.getWidth()-1)][Mathf.clamp(y / scaling, 0, pixmap.getHeight()-1)].tile());
|
input.begin(filter, editor.width(), editor.height(), (x, y) -> buffer1[Mathf.clamp(x / scaling, 0, pixmap.getWidth()-1)][Mathf.clamp(y / scaling, 0, pixmap.getHeight()-1)].tile());
|
||||||
|
|
||||||
//read from buffer1 and write to buffer2
|
//read from buffer1 and write to buffer2
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
pixmap.each((px, py) -> {
|
||||||
for(int py = 0; py < pixmap.getHeight(); py++){
|
int x = px * scaling, y = py * scaling;
|
||||||
int x = px * scaling, y = py * scaling;
|
GenTile tile = buffer1[px][py];
|
||||||
GenTile tile = buffer1[px][py];
|
input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
||||||
input.apply(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);
|
});
|
||||||
}
|
|
||||||
}
|
pixmap.each((px, py) -> buffer1[px][py].set(buffer2[px][py]));
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
|
||||||
for(int py = 0; py < pixmap.getHeight(); py++){
|
|
||||||
buffer1[px][py].set(buffer2[px][py]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
for(int px = 0; px < pixmap.getWidth(); px++){
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class MapRenderer implements Disposable{
|
|||||||
private void render(int wx, int wy){
|
private void render(int wx, int wy){
|
||||||
int x = wx / chunkSize, y = wy / chunkSize;
|
int x = wx / chunkSize, y = wy / chunkSize;
|
||||||
IndexedRenderer mesh = chunks[x][y];
|
IndexedRenderer mesh = chunks[x][y];
|
||||||
Tile tile = editor.tiles()[wx][wy];
|
Tile tile = editor.tiles().getn(wx, wy);
|
||||||
|
|
||||||
Team team = tile.getTeam();
|
Team team = tile.getTeam();
|
||||||
Block floor = tile.floor();
|
Block floor = tile.floor();
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class MenuRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generate(){
|
private void generate(){
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
||||||
shadows = new FrameBuffer(width, height);
|
shadows = new FrameBuffer(width, height);
|
||||||
int offset = Mathf.random(100000);
|
int offset = Mathf.random(100000);
|
||||||
@@ -155,7 +155,7 @@ public class MenuRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tile tile;
|
Tile tile;
|
||||||
tiles[x][y] = (tile = new CachedTile());
|
tiles.set(x, y, (tile = new CachedTile()));
|
||||||
tile.x = (short)x;
|
tile.x = (short)x;
|
||||||
tile.y = (short)y;
|
tile.y = (short)y;
|
||||||
tile.setFloor((Floor) floor);
|
tile.setFloor((Floor) floor);
|
||||||
|
|||||||
@@ -25,26 +25,6 @@ public class LegacyMapIO{
|
|||||||
private static final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad");
|
private static final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad");
|
||||||
private static final Json json = new Json();
|
private static final Json json = new Json();
|
||||||
|
|
||||||
/* Convert a map from the old format to the new format. */
|
|
||||||
public static void convertMap(FileHandle in, FileHandle out) throws IOException{
|
|
||||||
Map map = readMap(in, true);
|
|
||||||
|
|
||||||
String waves = map.tags.get("waves", "[]");
|
|
||||||
Array<SpawnGroup> groups = new Array<>(json.fromJson(SpawnGroup[].class, waves));
|
|
||||||
|
|
||||||
Tile[][] tiles = world.createTiles(map.width, map.height);
|
|
||||||
for(int x = 0; x < map.width; x++){
|
|
||||||
for(int y = 0; y < map.height; y++){
|
|
||||||
tiles[x][y] = new CachedTile();
|
|
||||||
tiles[x][y].x = (short)x;
|
|
||||||
tiles[x][y].y = (short)y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.rules.spawns = groups;
|
|
||||||
readTiles(map, tiles);
|
|
||||||
MapIO.writeMap(out, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
||||||
try(DataInputStream stream = new DataInputStream(file.read(1024))){
|
try(DataInputStream stream = new DataInputStream(file.read(1024))){
|
||||||
StringMap tags = new StringMap();
|
StringMap tags = new StringMap();
|
||||||
@@ -191,12 +171,12 @@ public class LegacyMapIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Reads a pixmap in the 3.5 pixmap format. */
|
/** Reads a pixmap in the 3.5 pixmap format. */
|
||||||
public static void readPixmap(Pixmap pixmap, Tile[][] tiles){
|
public static void readPixmap(Pixmap pixmap, Tiles tiles){
|
||||||
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++){
|
||||||
int color = pixmap.getPixel(x, pixmap.getHeight() - 1 - y);
|
int color = pixmap.getPixel(x, pixmap.getHeight() - 1 - y);
|
||||||
LegacyBlock block = LegacyColorMapper.get(color);
|
LegacyBlock block = LegacyColorMapper.get(color);
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
|
|
||||||
tile.setFloor(block.floor);
|
tile.setFloor(block.floor);
|
||||||
tile.setBlock(block.wall);
|
tile.setBlock(block.wall);
|
||||||
|
|||||||
@@ -132,11 +132,11 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pixmap generatePreview(Tile[][] tiles){
|
public static Pixmap generatePreview(Tiles tiles){
|
||||||
Pixmap pixmap = new Pixmap(tiles.length, tiles[0].length, Format.RGBA8888);
|
Pixmap pixmap = new Pixmap(tiles.width(), tiles.height(), Format.RGBA8888);
|
||||||
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.getn(x, y);
|
||||||
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
|
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class Maps{
|
|||||||
|
|
||||||
for(int x = 0; x < map.width; x++){
|
for(int x = 0; x < map.width; x++){
|
||||||
for(int y = 0; y < map.height; y++){
|
for(int y = 0; y < map.height; y++){
|
||||||
Tile tile = world.getTiles()[x][y];
|
Tile tile = world.rawTile(x, y);
|
||||||
|
|
||||||
if(tile.block() instanceof CoreBlock){
|
if(tile.block() instanceof CoreBlock){
|
||||||
map.teams.add(tile.getTeamID());
|
map.teams.add(tile.getTeamID());
|
||||||
@@ -182,7 +182,7 @@ public class Maps{
|
|||||||
Core.assets.unload(map.previewFile().path() + "." + mapExtension);
|
Core.assets.unload(map.previewFile().path() + "." + mapExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pixmap pix = MapIO.generatePreview(world.getTiles());
|
Pixmap pix = MapIO.generatePreview(world.tiles);
|
||||||
executor.submit(() -> map.previewFile().writePNG(pix));
|
executor.submit(() -> map.previewFile().writePNG(pix));
|
||||||
writeCache(map);
|
writeCache(map);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
@@ -11,16 +12,21 @@ public class BlendFilter extends GenerateFilter{
|
|||||||
float radius = 2f;
|
float radius = 2f;
|
||||||
Block block = Blocks.stone, floor = Blocks.ice, ignore = Blocks.air;
|
Block block = Blocks.stone, floor = Blocks.ice, ignore = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
||||||
new BlockOption("block", () -> block, b -> block = b, anyOptional),
|
new BlockOption("block", () -> block, b -> block = b, anyOptional),
|
||||||
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
|
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
|
||||||
new BlockOption("ignore", () -> ignore, b -> ignore = b, floorsOptional)
|
new BlockOption("ignore", () -> ignore, b -> ignore = b, floorsOptional)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
if(in.floor == block || block == Blocks.air || in.floor == ignore) return;
|
if(in.floor == block || block == Blocks.air || in.floor == ignore) return;
|
||||||
@@ -31,7 +37,7 @@ public class BlendFilter extends GenerateFilter{
|
|||||||
outer:
|
outer:
|
||||||
for(int x = -rad; x <= rad; x++){
|
for(int x = -rad; x <= rad; x++){
|
||||||
for(int y = -rad; y <= rad; y++){
|
for(int y = -rad; y <= rad; y++){
|
||||||
if(Mathf.dst2(x, y) > rad*rad) continue;
|
if(Mathf.within(x, y, rad)) continue;
|
||||||
Tile tile = in.tile(in.x + x, in.y + y);
|
Tile tile = in.tile(in.x + x, in.y + y);
|
||||||
|
|
||||||
if(tile.floor() == block || tile.block() == block || tile.overlay() == block){
|
if(tile.floor() == block || tile.block() == block || tile.overlay() == block){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
@@ -8,10 +9,9 @@ import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
|||||||
public class ClearFilter extends GenerateFilter{
|
public class ClearFilter extends GenerateFilter{
|
||||||
protected Block block = Blocks.air;
|
protected Block block = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
new BlockOption("block", () -> block, b -> block = b, wallsOnly)
|
return Structs.arr(new BlockOption("block", () -> block, b -> block = b, wallsOnly));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
|
import io.anuke.mindustry.content.*;
|
||||||
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.defaultTeam;
|
||||||
|
|
||||||
|
/** Selects X spawns from the core spawn pool.*/
|
||||||
|
public class CoreSpawnFilter extends GenerateFilter{
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("amount", () -> amount, f -> amount = (int)f, 1, 10)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
IntArray spawns = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.getTeam() == defaultTeam){
|
||||||
|
spawns.add(tile.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawns.shuffle();
|
||||||
|
|
||||||
|
int used = Math.min(spawns.size, amount);
|
||||||
|
for(int i = used; i < spawns.size; i++){
|
||||||
|
Tile tile = tiles.getp(spawns.get(i));
|
||||||
|
tile.setBlock(Blocks.air);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
@@ -7,14 +8,19 @@ import io.anuke.mindustry.world.blocks.*;
|
|||||||
public class DistortFilter extends GenerateFilter{
|
public class DistortFilter extends GenerateFilter{
|
||||||
float scl = 40, mag = 5;
|
float scl = 40, mag = 5;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 200f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 200f),
|
||||||
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
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);
|
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);
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
|
import io.anuke.mindustry.content.*;
|
||||||
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
|
/** Selects X spawns from the spawn pool.*/
|
||||||
|
public class EnemySpawnFilter extends GenerateFilter{
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("amount", () -> amount, f -> amount = (int)f, 1, 10)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
IntArray spawns = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.overlay() == Blocks.spawn){
|
||||||
|
spawns.add(tile.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawns.shuffle();
|
||||||
|
|
||||||
|
int used = Math.min(spawns.size, amount);
|
||||||
|
for(int i = used; i < spawns.size; i++){
|
||||||
|
Tile tile = tiles.getp(spawns.get(i));
|
||||||
|
tile.clearOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,34 +5,38 @@ import io.anuke.arc.math.*;
|
|||||||
import io.anuke.arc.scene.ui.*;
|
import io.anuke.arc.scene.ui.*;
|
||||||
import io.anuke.arc.util.*;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.arc.util.noise.*;
|
import io.anuke.arc.util.noise.*;
|
||||||
import io.anuke.mindustry.content.*;
|
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
|
||||||
|
|
||||||
public abstract class GenerateFilter{
|
public abstract class GenerateFilter{
|
||||||
protected transient float o = (float)(Math.random() * 10000000.0);
|
protected transient float o = (float)(Math.random() * 10000000.0);
|
||||||
protected transient long seed;
|
protected transient long seed;
|
||||||
protected transient GenerateInput in;
|
protected transient GenerateInput in;
|
||||||
|
|
||||||
public transient boolean buffered = false;
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
public transient FilterOption[] options;
|
this.in = in;
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
in.apply(tile.x, tile.y, tile.floor(), tile.block(), tile.overlay());
|
||||||
|
apply();
|
||||||
|
|
||||||
|
tile.setFloor(in.floor.asFloor());
|
||||||
|
tile.setOverlay(in.ore);
|
||||||
|
|
||||||
|
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||||
|
tile.setBlock(in.block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void apply(GenerateInput in){
|
public final void apply(GenerateInput in){
|
||||||
this.in = in;
|
this.in = in;
|
||||||
apply();
|
apply();
|
||||||
//remove extra ores on liquids
|
|
||||||
if(((Floor)in.floor).isLiquid){
|
|
||||||
in.ore = Blocks.air;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sets up the options; this is necessary since the constructor can't access subclass variables. */
|
/** @return a new array of options for configuring this filter */
|
||||||
protected void options(FilterOption... options){
|
public abstract FilterOption[] options();
|
||||||
this.options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** apply the actual filter on the input */
|
/** apply the actual filter on the input */
|
||||||
protected abstract void apply();
|
protected void apply(){}
|
||||||
|
|
||||||
/** draw any additional guides */
|
/** draw any additional guides */
|
||||||
public void draw(Image image){}
|
public void draw(Image image){}
|
||||||
@@ -47,6 +51,16 @@ public abstract class GenerateFilter{
|
|||||||
seed = Mathf.random(99999999);
|
seed = Mathf.random(99999999);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether this filter needs a read/write buffer (e.g. not a 1:1 tile mapping). */
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether this filter can *only* be used while generating the map, e.g. is not undoable. */
|
||||||
|
public boolean isPost(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//utility generation functions
|
//utility generation functions
|
||||||
|
|
||||||
protected float noise(float x, float y, float scl, float mag){
|
protected float noise(float x, float y, float scl, float mag){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.filters;
|
|||||||
|
|
||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
@@ -12,14 +13,19 @@ public class MedianFilter extends GenerateFilter{
|
|||||||
float percentile = 0.5f;
|
float percentile = 0.5f;
|
||||||
IntArray blocks = new IntArray(), floors = new IntArray();
|
IntArray blocks = new IntArray(), floors = new IntArray();
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
int rad = (int)radius;
|
int rad = (int)radius;
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ public class MirrorFilter extends GenerateFilter{
|
|||||||
|
|
||||||
int angle = 45;
|
int angle = 45;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(new SliderOption("angle", () -> angle, f -> angle = (int)f, 0, 360, 45));
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("angle", () -> angle, f -> angle = (int)f, 0, 360, 45)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.SliderOption;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.floorsOnly;
|
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.wallsOnly;
|
|
||||||
|
|
||||||
public class NoiseFilter extends GenerateFilter{
|
public class NoiseFilter extends GenerateFilter{
|
||||||
float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f;
|
float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f;
|
||||||
Block floor = Blocks.stone, block = Blocks.rocks;
|
Block floor = Blocks.stone, block = Blocks.rocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.SliderOption;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.oresOnly;
|
|
||||||
|
|
||||||
public class OreFilter extends GenerateFilter{
|
public class OreFilter extends GenerateFilter{
|
||||||
public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f;
|
public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f;
|
||||||
public Block ore = Blocks.oreCopper;
|
public Block ore = Blocks.oreCopper;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
return Structs.arr(
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f),
|
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
||||||
new BlockOption("ore", () -> ore, b -> ore = b, oresOnly)
|
new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f),
|
||||||
|
new BlockOption("ore", () -> ore, b -> ore = b, oresOnly)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.maps.filters;
|
|||||||
|
|
||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.*;
|
import io.anuke.mindustry.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
@@ -13,14 +14,19 @@ public class OreMedianFilter extends GenerateFilter{
|
|||||||
|
|
||||||
private IntArray blocks = new IntArray();
|
private IntArray blocks = new IntArray();
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
if(in.ore == Blocks.spawn) return;
|
if(in.ore == Blocks.spawn) return;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
|
import io.anuke.arc.math.*;
|
||||||
|
import io.anuke.mindustry.type.*;
|
||||||
|
import io.anuke.mindustry.world.*;
|
||||||
|
import io.anuke.mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
|
public class RandomItemFilter extends GenerateFilter{
|
||||||
|
public Array<ItemStack> drops = new Array<>();
|
||||||
|
public float chance = 0.3f;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return new FilterOption[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock)){
|
||||||
|
for(ItemStack stack : drops){
|
||||||
|
if(Mathf.chance(chance)){
|
||||||
|
tile.entity.items.add(stack.item, Math.min(Mathf.random(stack.amount), tile.block().itemCapacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.SliderOption;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.floorsOnly;
|
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.wallsOnly;
|
|
||||||
|
|
||||||
public class RiverNoiseFilter extends GenerateFilter{
|
public class RiverNoiseFilter extends GenerateFilter{
|
||||||
float scl = 40, threshold = 0f, threshold2 = 0.1f;
|
float scl = 40, threshold = 0f, threshold2 = 0.1f;
|
||||||
Block floor = Blocks.water, floor2 = Blocks.deepwater, block = Blocks.sandRocks;
|
Block floor = Blocks.water, floor2 = Blocks.deepwater, block = Blocks.sandRocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, -1f, 0.3f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, -1f, 0.3f),
|
||||||
new SliderOption("threshold2", () -> threshold2, f -> threshold2 = f, -1f, 0.3f),
|
new SliderOption("threshold2", () -> threshold2, f -> threshold2 = f, -1f, 0.3f),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.SliderOption;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
|
|
||||||
@@ -11,8 +11,9 @@ public class ScatterFilter extends GenerateFilter{
|
|||||||
protected float chance = 0.014f;
|
protected float chance = 0.014f;
|
||||||
protected Block flooronto = Blocks.air, floor = Blocks.air, block = Blocks.air;
|
protected Block flooronto = Blocks.air, floor = Blocks.air, block = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("chance", () -> chance, f -> chance = f, 0f, 1f),
|
new SliderOption("chance", () -> chance, f -> chance = f, 0f, 1f),
|
||||||
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOptional),
|
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOptional),
|
||||||
new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional),
|
new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional),
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package io.anuke.mindustry.maps.filters;
|
package io.anuke.mindustry.maps.filters;
|
||||||
|
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.filters.FilterOption.SliderOption;
|
import io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.floorsOnly;
|
import static io.anuke.mindustry.maps.filters.FilterOption.*;
|
||||||
import static io.anuke.mindustry.maps.filters.FilterOption.wallsOnly;
|
|
||||||
|
|
||||||
public class TerrainFilter extends GenerateFilter{
|
public class TerrainFilter extends GenerateFilter{
|
||||||
float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f;
|
float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f;
|
||||||
Block floor = Blocks.stone, block = Blocks.rocks;
|
Block floor = Blocks.stone, block = Blocks.rocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("mag", () -> magnitude, f -> magnitude = f, 0f, 2f),
|
new SliderOption("mag", () -> magnitude, f -> magnitude = f, 0f, 2f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
int seed = Mathf.random(99999999);
|
int seed = Mathf.random(99999999);
|
||||||
sim.setSeed(seed);
|
sim.setSeed(seed);
|
||||||
sim2.setSeed(seed + 1);
|
sim2.setSeed(seed + 1);
|
||||||
super.generate(tiles);
|
super.generate(tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ores(Tile[][] tiles){
|
public void ores(Tiles tiles){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(ores != null){
|
if(ores != null){
|
||||||
int offsetX = x - 4, offsetY = y + 23;
|
int offsetX = x - 4, offsetY = y + 23;
|
||||||
@@ -49,7 +49,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terrain(Tile[][] tiles, Block dst, float scl, float mag, float cmag){
|
public void terrain(Tiles tiles, Block dst, float scl, float mag, float cmag){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
double rocks = sim.octaveNoise2D(5, 0.5, 1f / scl, x, y) * mag
|
double rocks = sim.octaveNoise2D(5, 0.5, 1f / scl, x, y) * mag
|
||||||
+ Mathf.dst((float)x / width, (float)y / height, 0.5f, 0.5f) * cmag;
|
+ Mathf.dst((float)x / width, (float)y / height, 0.5f, 0.5f) * cmag;
|
||||||
@@ -66,11 +66,11 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void noise(Tile[][] tiles, Block floor, Block block, int octaves, float falloff, float scl, float threshold){
|
public void noise(Tiles tiles, Block floor, Block block, int octaves, float falloff, float scl, float threshold){
|
||||||
sim.setSeed(Mathf.random(99999));
|
sim.setSeed(Mathf.random(99999));
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold){
|
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
this.floor = floor;
|
this.floor = floor;
|
||||||
if(tile.block().solid){
|
if(tile.block().solid){
|
||||||
this.block = block;
|
this.block = block;
|
||||||
@@ -79,16 +79,16 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void overlay(Tile[][] tiles, Block floor, Block block, float chance, int octaves, float falloff, float scl, float threshold){
|
public void overlay(Tiles tiles, Block floor, Block block, float chance, int octaves, float falloff, float scl, float threshold){
|
||||||
sim.setSeed(Mathf.random(99999));
|
sim.setSeed(Mathf.random(99999));
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold && Mathf.chance(chance) && tiles[x][y].floor() == floor){
|
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold && Mathf.chance(chance) && tiles.getn(x, y).floor() == floor){
|
||||||
ore = block;
|
ore = block;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tech(Tile[][] tiles){
|
public void tech(Tiles tiles){
|
||||||
Block[] blocks = {Blocks.darkPanel3};
|
Block[] blocks = {Blocks.darkPanel3};
|
||||||
int secSize = 20;
|
int secSize = 20;
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
@@ -109,13 +109,13 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void distort(Tile[][] tiles, float scl, float mag){
|
public void distort(Tiles tiles, float scl, float mag){
|
||||||
Block[][] blocks = new Block[width][height];
|
Block[][] blocks = new Block[width][height];
|
||||||
Floor[][] floors = new Floor[width][height];
|
Floor[][] floors = new Floor[width][height];
|
||||||
|
|
||||||
each((x, y) -> {
|
each((x, y) -> {
|
||||||
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 1525215f, scl, mag) - mag / 2f;
|
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 1525215f, scl, mag) - mag / 2f;
|
||||||
Tile other = tiles[Mathf.clamp((int)cx, 0, width-1)][Mathf.clamp((int)cy, 0, height-1)];
|
Tile other = tiles.getn(Mathf.clamp((int)cx, 0, width-1), Mathf.clamp((int)cy, 0, height-1));
|
||||||
blocks[x][y] = other.block();
|
blocks[x][y] = other.block();
|
||||||
floors[x][y] = other.floor();
|
floors[x][y] = other.floor();
|
||||||
});
|
});
|
||||||
@@ -126,7 +126,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scatter(Tile[][] tiles, Block target, Block dst, float chance){
|
public void scatter(Tiles tiles, Block target, Block dst, float chance){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(!Mathf.chance(chance)) return;
|
if(!Mathf.chance(chance)) return;
|
||||||
if(floor == target){
|
if(floor == target){
|
||||||
@@ -149,40 +149,40 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
return (float)sim2.octaveNoise2D(1f, 0f, 1f / scl, x + 0x361266f, y + 0x251259f) * mag;
|
return (float)sim2.octaveNoise2D(1f, 0f, 1f / scl, x + 0x361266f, y + 0x251259f) * mag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pass(Tile[][] tiles, Intc2 r){
|
public void pass(Tiles tiles, Intc2 r){
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
floor = tiles[x][y].floor();
|
floor = tiles.getn(x, y).floor();
|
||||||
block = tiles[x][y].block();
|
block = tiles.getn(x, y).block();
|
||||||
ore = tiles[x][y].overlay();
|
ore = tiles.getn(x, y).overlay();
|
||||||
r.get(x, y);
|
r.get(x, y);
|
||||||
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
|
tiles.set(x, y, new Tile(x, y, floor.id, ore.id, block.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void brush(Tile[][] tiles, Array<Tile> path, int rad){
|
public void brush(Tiles tiles, Array<Tile> path, int rad){
|
||||||
path.each(tile -> erase(tiles, tile.x, tile.y, rad));
|
path.each(tile -> erase(tiles, tile.x, tile.y, rad));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void erase(Tile[][] tiles, int cx, int cy, int rad){
|
public void erase(Tiles tiles, int cx, int cy, int rad){
|
||||||
for(int x = -rad; x <= rad; x++){
|
for(int x = -rad; x <= rad; x++){
|
||||||
for(int y = -rad; y <= rad; y++){
|
for(int y = -rad; y <= rad; y++){
|
||||||
int wx = cx + x, wy = cy + y;
|
int wx = cx + x, wy = cy + y;
|
||||||
if(Structs.inBounds(wx, wy, width, height) && Mathf.dst(x, y, 0, 0) <= rad){
|
if(Structs.inBounds(wx, wy, width, height) && Mathf.dst(x, y, 0, 0) <= rad){
|
||||||
Tile other = tiles[wx][wy];
|
Tile other = tiles.getn(wx, wy);
|
||||||
other.setBlock(Blocks.air);
|
other.setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<Tile> pathfind(Tile[][] tiles, int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
public Array<Tile> pathfind(Tiles tiles, int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
||||||
Tile start = tiles[startX][startY];
|
Tile start = tiles.getn(startX, startY);
|
||||||
Tile end = tiles[endX][endY];
|
Tile end = tiles.getn(endX, endY);
|
||||||
GridBits closed = new GridBits(width, height);
|
GridBits closed = new GridBits(width, height);
|
||||||
IntFloatMap costs = new IntFloatMap();
|
IntFloatMap costs = new IntFloatMap();
|
||||||
PriorityQueue<Tile> queue = new PriorityQueue<>(tiles.length * tiles[0].length / 2, (a, b) -> Float.compare(costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y), costs.get(b.pos(), 0f) + dh.cost(b.x, b.y, end.x, end.y)));
|
PriorityQueue<Tile> queue = new PriorityQueue<>(tiles.width() * tiles.height()/4, (a, b) -> Float.compare(costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y), costs.get(b.pos(), 0f) + dh.cost(b.x, b.y, end.x, end.y)));
|
||||||
queue.add(start);
|
queue.add(start);
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
while(!queue.isEmpty()){
|
while(!queue.isEmpty()){
|
||||||
@@ -196,7 +196,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newx = next.x + point.x, newy = next.y + point.y;
|
int newx = next.x + point.x, newy = next.y + point.y;
|
||||||
if(Structs.inBounds(newx, newy, width, height)){
|
if(Structs.inBounds(newx, newy, width, height)){
|
||||||
Tile child = tiles[newx][newy];
|
Tile child = tiles.getn(newx, newy);
|
||||||
if(!closed.get(child.x, child.y)){
|
if(!closed.get(child.x, child.y)){
|
||||||
closed.set(child.x, child.y);
|
closed.set(child.x, child.y);
|
||||||
child.rotation(child.relativeTo(next.x, next.y));
|
child.rotation(child.relativeTo(next.x, next.y));
|
||||||
@@ -215,7 +215,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
while(current != start){
|
while(current != start){
|
||||||
out.add(current);
|
out.add(current);
|
||||||
Point2 p = Geometry.d4(current.rotation());
|
Point2 p = Geometry.d4(current.rotation());
|
||||||
current = tiles[current.x + p.x][current.y + p.y];
|
current = tiles.getn(current.x + p.x, current.y + p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.reverse();
|
out.reverse();
|
||||||
@@ -223,17 +223,17 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inverseFloodFill(Tile[][] tiles, Tile start, Block block){
|
public void inverseFloodFill(Tiles tiles, Tile start, Block block){
|
||||||
IntArray arr = new IntArray();
|
IntArray arr = new IntArray();
|
||||||
arr.add(start.pos());
|
arr.add(start.pos());
|
||||||
while(!arr.isEmpty()){
|
while(!arr.isEmpty()){
|
||||||
int i = arr.pop();
|
int i = arr.pop();
|
||||||
int x = Pos.x(i), y = Pos.y(i);
|
int x = Pos.x(i), y = Pos.y(i);
|
||||||
tiles[x][y].cost = 2;
|
tiles.getn(x, y).cost = 2;
|
||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newx = x + point.x, newy = y + point.y;
|
int newx = x + point.x, newy = y + point.y;
|
||||||
if(Structs.inBounds(newx, newy, width, height)){
|
if(tiles.in(newx, newy)){
|
||||||
Tile child = tiles[newx][newy];
|
Tile child = tiles.getn(newx, newy);
|
||||||
if(child.block() == Blocks.air && child.cost != 2){
|
if(child.block() == Blocks.air && child.cost != 2){
|
||||||
child.cost = 2;
|
child.cost = 2;
|
||||||
arr.add(child.pos());
|
arr.add(child.pos());
|
||||||
@@ -244,7 +244,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
|
|
||||||
for(int x = 0; x < width; x ++){
|
for(int x = 0; x < width; x ++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
if(tile.cost != 2 && tile.block() == Blocks.air){
|
if(tile.cost != 2 && tile.block() == Blocks.air){
|
||||||
tile.setBlock(block);
|
tile.setBlock(block);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ public abstract class Generator{
|
|||||||
this.loadout = loadout;
|
this.loadout = loadout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void generate(Tile[][] tiles);
|
public abstract void generate(Tiles tiles);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
package io.anuke.mindustry.maps.generators;
|
package io.anuke.mindustry.maps.generators;
|
||||||
|
|
||||||
import io.anuke.arc.collection.*;
|
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.*;
|
import io.anuke.arc.math.geom.*;
|
||||||
import io.anuke.arc.util.*;
|
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.game.*;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.io.*;
|
import io.anuke.mindustry.io.*;
|
||||||
import io.anuke.mindustry.maps.*;
|
import io.anuke.mindustry.maps.*;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
|
||||||
import io.anuke.mindustry.world.blocks.storage.*;
|
import io.anuke.mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
@@ -44,97 +41,43 @@ public class MapGenerator extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
for(int x = 0; x < width; x++){
|
tiles.fill();
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
tiles[x][y] = new Tile(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveIO.load(map.file);
|
SaveIO.load(map.file);
|
||||||
Array<Point2> players = new Array<>();
|
|
||||||
Array<Point2> enemies = new Array<>();
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height; y++){
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
||||||
if(tiles[x][y].block() instanceof CoreBlock && tiles[x][y].getTeam() == defaultTeam){
|
for(Item item : world.getZone().resources){
|
||||||
players.add(new Point2(x, y));
|
if(Mathf.chance(0.3)){
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
tile.entity.items.add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].overlay() == Blocks.spawn && enemySpawns != -1){
|
|
||||||
enemies.add(new Point2(x, y));
|
|
||||||
tiles[x][y].setOverlay(Blocks.air);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].block() instanceof BlockPart){
|
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
|
|
||||||
for(Decoration decor : decorations){
|
|
||||||
if(x > 0 && y > 0 && (tiles[x - 1][y].block() == decor.wall || tiles[x][y - 1].block() == decor.wall)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){
|
|
||||||
tile.setBlock(decor.wall);
|
|
||||||
}else if(tile.floor() == decor.floor && decor.wall.isOverlay() && Mathf.chance(decor.chance)){
|
|
||||||
tile.setOverlay(decor.wall);
|
|
||||||
}else if(tile.floor() == decor.floor && decor.wall.isFloor() && !decor.wall.isOverlay() && Mathf.chance(decor.chance)){
|
|
||||||
tile.setFloor((Floor)decor.wall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
|
||||||
for(Item item : world.getZone().resources){
|
|
||||||
if(Mathf.chance(0.3)){
|
|
||||||
tile.entity.items.add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemySpawns != -1){
|
boolean anyCores = false;
|
||||||
if(enemySpawns > enemies.size){
|
|
||||||
throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number for map: " + mapName);
|
for(Tile tile : tiles){
|
||||||
|
if(tile.overlay() == Blocks.spawn){
|
||||||
|
int rad = 10;
|
||||||
|
Geometry.circle(tile.x, tile.y, tiles.width(), tiles.height(), rad, (wx, wy) -> {
|
||||||
|
if(tile.overlay().itemDrop != null){
|
||||||
|
tile.clearOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
enemies.shuffle();
|
if(tile.block() instanceof CoreBlock && tile.getTeam() == defaultTeam){
|
||||||
for(int i = 0; i < enemySpawns; i++){
|
schematics.placeLoadout(loadout, tile.x, tile.y);
|
||||||
Point2 point = enemies.get(i);
|
anyCores = true;
|
||||||
tiles[point.x][point.y].setOverlay(Blocks.spawn);
|
|
||||||
|
|
||||||
int rad = 10, frad = 12;
|
|
||||||
|
|
||||||
for(int x = -rad; x <= rad; x++){
|
|
||||||
for(int y = -rad; y <= rad; y++){
|
|
||||||
int wx = x + point.x, wy = y + point.y;
|
|
||||||
double dst = Mathf.dst(x, y);
|
|
||||||
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
|
|
||||||
Tile tile = tiles[wx][wy];
|
|
||||||
if(tile.overlay() != Blocks.spawn){
|
|
||||||
tile.clearOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2 core = players.random();
|
if(!anyCores){
|
||||||
if(core == null){
|
|
||||||
throw new IllegalArgumentException("All zone maps must have a core.");
|
throw new IllegalArgumentException("All zone maps must have a core.");
|
||||||
}
|
}
|
||||||
|
|
||||||
schematics.placeLoadout(loadout, core.x, core.y);
|
|
||||||
|
|
||||||
world.prepareTiles(tiles);
|
world.prepareTiles(tiles);
|
||||||
world.setMap(map);
|
world.setMap(map);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package io.anuke.mindustry.maps.generators;
|
package io.anuke.mindustry.maps.generators;
|
||||||
|
|
||||||
import io.anuke.arc.collection.StringMap;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.*;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
@@ -18,14 +17,14 @@ public abstract class RandomGenerator extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
floor = Blocks.air;
|
floor = Blocks.air;
|
||||||
block = Blocks.air;
|
block = Blocks.air;
|
||||||
ore = Blocks.air;
|
ore = Blocks.air;
|
||||||
generate(x, y);
|
generate(x, y);
|
||||||
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
|
tiles.set(x, y, new Tile(x, y, floor.id, ore.id, block.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ public abstract class RandomGenerator extends Generator{
|
|||||||
world.setMap(new Map(new StringMap()));
|
world.setMap(new Map(new StringMap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void decorate(Tile[][] tiles);
|
public abstract void decorate(Tiles tiles);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link #floor} and {@link #block} to the correct values as output.
|
* Sets {@link #floor} and {@link #block} to the correct values as output.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package io.anuke.mindustry.maps.zonegen;
|
package io.anuke.mindustry.maps.zonegen;
|
||||||
|
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.generators.BasicGenerator;
|
import io.anuke.mindustry.maps.generators.*;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.schematics;
|
import static io.anuke.mindustry.Vars.schematics;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decorate(Tile[][] tiles){
|
public void decorate(Tiles tiles){
|
||||||
ores(tiles);
|
ores(tiles);
|
||||||
terrain(tiles, Blocks.sandRocks, 60f, 1.5f, 0.9f);
|
terrain(tiles, Blocks.sandRocks, 60f, 1.5f, 0.9f);
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
erase(tiles, endX, endY, 10);
|
erase(tiles, endX, endY, 10);
|
||||||
erase(tiles, spawnX, spawnY, 20);
|
erase(tiles, spawnX, spawnY, 20);
|
||||||
distort(tiles, 20f, 4f);
|
distort(tiles, 20f, 4f);
|
||||||
inverseFloodFill(tiles, tiles[spawnX][spawnY], Blocks.sandRocks);
|
inverseFloodFill(tiles, tiles.getn(spawnX, spawnY), Blocks.sandRocks);
|
||||||
|
|
||||||
noise(tiles, Blocks.salt, Blocks.saltRocks, 5, 0.6f, 200f, 0.55f);
|
noise(tiles, Blocks.salt, Blocks.saltRocks, 5, 0.6f, 200f, 0.55f);
|
||||||
noise(tiles, Blocks.darksand, Blocks.duneRocks, 5, 0.7f, 120f, 0.5f);
|
noise(tiles, Blocks.darksand, Blocks.duneRocks, 5, 0.7f, 120f, 0.5f);
|
||||||
@@ -43,7 +43,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
|
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
|
||||||
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
|
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
|
||||||
|
|
||||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
tiles.getn(endX, endY).setOverlay(Blocks.spawn);
|
||||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package io.anuke.mindustry.maps.zonegen;
|
package io.anuke.mindustry.maps.zonegen;
|
||||||
|
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.maps.generators.BasicGenerator;
|
import io.anuke.mindustry.maps.generators.*;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.schematics;
|
import static io.anuke.mindustry.Vars.schematics;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public class OvergrowthGenerator extends BasicGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decorate(Tile[][] tiles){
|
public void decorate(Tiles tiles){
|
||||||
ores(tiles);
|
ores(tiles);
|
||||||
terrain(tiles, Blocks.sporePine, 70f, 1.4f, 1f);
|
terrain(tiles, Blocks.sporePine, 70f, 1.4f, 1f);
|
||||||
|
|
||||||
@@ -34,12 +34,12 @@ public class OvergrowthGenerator extends BasicGenerator{
|
|||||||
erase(tiles, endX, endY, 10);
|
erase(tiles, endX, endY, 10);
|
||||||
erase(tiles, spawnX, spawnY, 20);
|
erase(tiles, spawnX, spawnY, 20);
|
||||||
distort(tiles, 20f, 4f);
|
distort(tiles, 20f, 4f);
|
||||||
inverseFloodFill(tiles, tiles[spawnX][spawnY], Blocks.sporerocks);
|
inverseFloodFill(tiles, tiles.getn(spawnX, spawnY), Blocks.sporerocks);
|
||||||
|
|
||||||
noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
|
noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
|
||||||
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
|
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
|
||||||
|
|
||||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
tiles.getn(endX, endY).setOverlay(Blocks.spawn);
|
||||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
84
core/src/io/anuke/mindustry/world/Tiles.java
Normal file
84
core/src/io/anuke/mindustry/world/Tiles.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
|
import io.anuke.arc.util.ArcAnnotate.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/** A tile container. */
|
||||||
|
public class Tiles implements Iterable<Tile>{
|
||||||
|
private final Tile[] array;
|
||||||
|
private final int width, height;
|
||||||
|
private final TileIterator iterator = new TileIterator();
|
||||||
|
|
||||||
|
public Tiles(int width, int height){
|
||||||
|
this.array = new Tile[width * height];
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** fills this tile set with empty air tiles. */
|
||||||
|
public void fill(){
|
||||||
|
for(int i = 0; i < array.length; i++){
|
||||||
|
array[i] = new Tile(i % width, i / width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** set a tile at a position; does not range-check. use with caution. */
|
||||||
|
public void set(int x, int y, Tile tile){
|
||||||
|
array[y*width + x] = tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether these coordinates are in bounds */
|
||||||
|
public boolean in(int x, int y){
|
||||||
|
return x >= 0 && x < width && y >= 0 && y < height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at coordinates, or null if out of bounds */
|
||||||
|
public @Nullable Tile get(int x, int y){
|
||||||
|
return (x < 0 || x >= width || y < 0 || y >= height) ? null : array[y*width + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at coordinates; throws an exception if out of bounds */
|
||||||
|
public @NonNull Tile getn(int x, int y){
|
||||||
|
if(x < 0 || x >= width || y < 0 || y >= height) throw new IllegalArgumentException(x + ", " + y + " out of bounds: width=" + width + ", height=" + height);
|
||||||
|
return array[y*width + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at an iteration index [0, width * height] */
|
||||||
|
public @NonNull Tile geti(int idx){
|
||||||
|
return array[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at an int position (not equivalent to geti) */
|
||||||
|
public @Nullable Tile getp(int pos){
|
||||||
|
return get(Pos.x(pos), Pos.y(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int width(){
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int height(){
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Tile> iterator(){
|
||||||
|
iterator.index = 0;
|
||||||
|
return iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TileIterator implements Iterator<Tile>{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext(){
|
||||||
|
return index < array.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tile next(){
|
||||||
|
return array[index++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import io.anuke.arc.graphics.g2d.*;
|
|||||||
import io.anuke.arc.graphics.g2d.TextureAtlas.*;
|
import io.anuke.arc.graphics.g2d.TextureAtlas.*;
|
||||||
import io.anuke.arc.math.*;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.geom.*;
|
import io.anuke.arc.math.geom.*;
|
||||||
|
import io.anuke.arc.util.ArcAnnotate.*;
|
||||||
import io.anuke.mindustry.content.*;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.entities.Effects.*;
|
import io.anuke.mindustry.entities.Effects.*;
|
||||||
import io.anuke.mindustry.type.*;
|
import io.anuke.mindustry.type.*;
|
||||||
@@ -33,13 +34,13 @@ public class Floor extends Block{
|
|||||||
/** Effect displayed when drowning on this floor. */
|
/** Effect displayed when drowning on this floor. */
|
||||||
public Effect drownUpdateEffect = Fx.bubble;
|
public Effect drownUpdateEffect = Fx.bubble;
|
||||||
/** Status effect applied when walking on. */
|
/** Status effect applied when walking on. */
|
||||||
public StatusEffect status = StatusEffects.none;
|
public @NonNull StatusEffect status = StatusEffects.none;
|
||||||
/** Intensity of applied status effect. */
|
/** Intensity of applied status effect. */
|
||||||
public float statusDuration = 60f;
|
public float statusDuration = 60f;
|
||||||
/** liquids that drop from this block, used for pumps */
|
/** liquids that drop from this block, used for pumps */
|
||||||
public Liquid liquidDrop = null;
|
public @Nullable Liquid liquidDrop = null;
|
||||||
/** item that drops from this block, used for drills */
|
/** item that drops from this block, used for drills */
|
||||||
public Item itemDrop = null;
|
public @Nullable Item itemDrop = null;
|
||||||
/** whether this block can be drowned in */
|
/** whether this block can be drowned in */
|
||||||
public boolean isLiquid;
|
public boolean isLiquid;
|
||||||
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=9cde8aeb1f4913d5f9c1ed1792d5c5c5d522298c
|
archash=640a9a5546f742c272c6117ea4ad886c80cd84ef
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createMap(){
|
void createMap(){
|
||||||
Tile[][] tiles = world.createTiles(8, 8);
|
Tile[][] tiles = world.resize(8, 8);
|
||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(int x = 0; x < tiles.length; x++){
|
||||||
@@ -329,7 +329,7 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allBlockTest(){
|
void allBlockTest(){
|
||||||
Tile[][] tiles = world.createTiles(256*2 + 20, 10);
|
Tile[][] tiles = world.resize(256*2 + 20, 10);
|
||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(int x = 0; x < tiles.length; x++){
|
||||||
|
|||||||
Reference in New Issue
Block a user