Classes moved / Fixed autotile bugs / Added sector display
This commit is contained in:
@@ -5,15 +5,18 @@ import com.badlogic.gdx.graphics.Pixmap.Format;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult;
|
||||
import io.anuke.mindustry.world.ColorMapper;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.GridMap;
|
||||
|
||||
import static io.anuke.mindustry.Vars.headless;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Sectors{
|
||||
private static final int sectorSize = 256;
|
||||
private static final int sectorImageSize = 8;
|
||||
private static final int sectorImageSize = 16;
|
||||
|
||||
private GridMap<Sector> grid = new GridMap<>();
|
||||
|
||||
public Sectors(){
|
||||
@@ -32,8 +35,9 @@ public class Sectors{
|
||||
sector.unlocked = true;
|
||||
if(sector.texture == null) createTexture(sector);
|
||||
|
||||
//TODO fix
|
||||
for(GridPoint2 point : Geometry.d4){
|
||||
createSector(sector.x + point.x, sector.y + point.y);
|
||||
// createSector(sector.x + point.x, sector.y + point.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +49,7 @@ public class Sectors{
|
||||
sector.x = (short)x;
|
||||
sector.y = (short)y;
|
||||
sector.unlocked = false;
|
||||
grid.put(x, y, sector);
|
||||
}
|
||||
|
||||
public void load(){
|
||||
@@ -74,9 +79,15 @@ public class Sectors{
|
||||
|
||||
int worldX = sector.x * sectorSize;
|
||||
int worldY = sector.y * sectorSize;
|
||||
for(int x = worldX; x < (worldX + sectorSize); x++){
|
||||
for(int y = worldY; y < (worldY + sectorSize); y++){
|
||||
for(int x = 0; x < sectorImageSize; x++){
|
||||
for(int y = 0; y < sectorImageSize; y++){
|
||||
int toX = x * sectorSize / sectorImageSize;
|
||||
int toY = y * sectorSize / sectorImageSize;
|
||||
|
||||
GenResult result = world.generator().generateTile(sector.x, sector.y, toX, toY);
|
||||
|
||||
int color = ColorMapper.getBlockColor(result.wall == Blocks.air ? result.floor : result.wall);
|
||||
pixmap.drawPixel(x, sectorImageSize - 1 - y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
115
core/src/io/anuke/mindustry/maps/generation/GenProperties.java
Normal file
115
core/src/io/anuke/mindustry/maps/generation/GenProperties.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
|
||||
public class GenProperties{
|
||||
public long seed;
|
||||
public MapStyle maps;
|
||||
public OreStyle ores;
|
||||
public RiverType riverType;
|
||||
public RiverStyle rivers;
|
||||
public TerrainStyle terrains;
|
||||
public FoliageStyle foliage;
|
||||
public EnvironmentStyle environment;
|
||||
|
||||
enum MapStyle{
|
||||
/**
|
||||
* 256x512
|
||||
*/
|
||||
longY,
|
||||
/**
|
||||
* 128x256
|
||||
*/
|
||||
smallY,
|
||||
/**
|
||||
* 128x128
|
||||
*/
|
||||
small,
|
||||
/**
|
||||
* 256x256
|
||||
*/
|
||||
normal
|
||||
}
|
||||
|
||||
enum OreStyle{
|
||||
/**
|
||||
* 'vanilla' noise-distributed ores
|
||||
*/
|
||||
normal,
|
||||
/**
|
||||
* ores hug the walls
|
||||
*/
|
||||
nearWalls,
|
||||
/**
|
||||
* ores hug all liquid rivers
|
||||
*/
|
||||
nearRivers,
|
||||
/**
|
||||
* large veins
|
||||
*/
|
||||
largeVeins
|
||||
}
|
||||
|
||||
enum RiverType{
|
||||
lava,
|
||||
water,
|
||||
oil,
|
||||
none
|
||||
}
|
||||
|
||||
enum RiverStyle{
|
||||
/**
|
||||
* long thin river spanning entire map
|
||||
*/
|
||||
longThin,
|
||||
/**
|
||||
* long river branching into many others
|
||||
*/
|
||||
longBranch,
|
||||
/**
|
||||
* one long, thick river
|
||||
*/
|
||||
longThick,
|
||||
/**
|
||||
* short, thick river that ends in a lake
|
||||
*/
|
||||
shortLake
|
||||
}
|
||||
|
||||
enum TerrainStyle{
|
||||
/**
|
||||
* bordered around by the normal material
|
||||
*/
|
||||
normal,
|
||||
/**
|
||||
* everything is islands
|
||||
*/
|
||||
waterIslands,
|
||||
/**
|
||||
* everything is islands: lava edition
|
||||
*/
|
||||
lavaIslands
|
||||
}
|
||||
|
||||
enum FoliageStyle{
|
||||
patches,
|
||||
veins,
|
||||
blobs,
|
||||
ridges
|
||||
}
|
||||
|
||||
enum FoilageType{
|
||||
grass,
|
||||
sand,
|
||||
darkStone,
|
||||
ice,
|
||||
}
|
||||
|
||||
enum EnvironmentStyle{
|
||||
desert,
|
||||
stoneDesert,
|
||||
grassy,
|
||||
dark,
|
||||
darkStone,
|
||||
stone,
|
||||
icy,
|
||||
}
|
||||
}
|
||||
285
core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java
Normal file
285
core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java
Normal file
@@ -0,0 +1,285 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntArray;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.content.blocks.OreBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.MapTileData;
|
||||
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.Floor;
|
||||
import io.anuke.ucore.noise.RidgedPerlin;
|
||||
import io.anuke.ucore.noise.Simplex;
|
||||
import io.anuke.ucore.util.Bits;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.SeedRandom;
|
||||
|
||||
import static io.anuke.mindustry.Vars.sectorSize;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
|
||||
public class WorldGenerator{
|
||||
private final int seed = 0;
|
||||
private int oreIndex = 0;
|
||||
|
||||
private Simplex sim = new Simplex(seed);
|
||||
private Simplex sim2 = new Simplex(seed + 1);
|
||||
private Simplex sim3 = new Simplex(seed + 2);
|
||||
|
||||
private SeedRandom random = new SeedRandom(seed + 3);
|
||||
|
||||
private GenResult result = new GenResult();
|
||||
private ObjectMap<Block, Block> decoration;
|
||||
|
||||
public WorldGenerator(){
|
||||
decoration = Mathf.map(
|
||||
Blocks.grass, Blocks.shrub,
|
||||
Blocks.stone, Blocks.rock,
|
||||
Blocks.ice, Blocks.icerock,
|
||||
Blocks.snow, Blocks.icerock,
|
||||
Blocks.blackstone, Blocks.blackrock
|
||||
);
|
||||
}
|
||||
|
||||
/**Loads raw map tile data into a Tile[][] array, setting up multiblocks, cliffs and ores. */
|
||||
public void loadTileData(Tile[][] tiles, MapTileData data, boolean genOres, int seed){
|
||||
data.position(0, 0);
|
||||
TileDataMarker marker = data.newDataMarker();
|
||||
|
||||
for(int y = 0; y < data.height(); y++){
|
||||
for(int x = 0; x < data.width(); x++){
|
||||
data.read(marker);
|
||||
|
||||
tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team, marker.elevation);
|
||||
}
|
||||
}
|
||||
|
||||
prepareTiles(tiles, seed, genOres);
|
||||
}
|
||||
|
||||
public void prepareTiles(Tile[][] tiles, int seed, boolean genOres){
|
||||
|
||||
//find multiblocks
|
||||
IntArray multiblocks = new IntArray();
|
||||
|
||||
for(int x = 0; x < tiles.length; x++){
|
||||
for(int y = 0; y < tiles[0].length; y++){
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
Team team = tile.getTeam();
|
||||
|
||||
if(tile.block() == StorageBlocks.core &&
|
||||
state.teams.has(team)){
|
||||
state.teams.get(team).cores.add(tile);
|
||||
}
|
||||
|
||||
if(tiles[x][y].block().isMultiblock()){
|
||||
multiblocks.add(tiles[x][y].packedPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//place multiblocks now
|
||||
for(int i = 0; i < multiblocks.size; i++){
|
||||
int pos = multiblocks.get(i);
|
||||
|
||||
int x = pos % tiles.length;
|
||||
int y = pos / tiles[0].length;
|
||||
|
||||
Block result = tiles[x][y].block();
|
||||
Team team = tiles[x][y].getTeam();
|
||||
|
||||
int offsetx = -(result.size - 1) / 2;
|
||||
int offsety = -(result.size - 1) / 2;
|
||||
|
||||
for(int dx = 0; dx < result.size; dx++){
|
||||
for(int dy = 0; dy < result.size; dy++){
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if(!(worldx == x && worldy == y)){
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if(toplace != null){
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//update cliffs, occlusion data
|
||||
for(int x = 0; x < tiles.length; x++){
|
||||
for(int y = 0; y < tiles[0].length; y++){
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
tile.updateOcclusion();
|
||||
|
||||
//fix things on cliffs that shouldn't be
|
||||
if(tile.block() != Blocks.air && tile.cliffs != 0){
|
||||
tile.setBlock(Blocks.air);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oreIndex = 0;
|
||||
|
||||
if(genOres){
|
||||
Array<OreEntry> ores = Array.with(
|
||||
new OreEntry(Items.tungsten, 0.3f, seed),
|
||||
new OreEntry(Items.coal, 0.284f, seed),
|
||||
new OreEntry(Items.lead, 0.28f, seed),
|
||||
new OreEntry(Items.titanium, 0.27f, seed),
|
||||
new OreEntry(Items.thorium, 0.26f, seed)
|
||||
);
|
||||
|
||||
for(int x = 0; x < tiles.length; x++){
|
||||
for(int y = 0; y < tiles[0].length; y++){
|
||||
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
if(!tile.floor().hasOres || tile.cliffs != 0 || tile.block() != Blocks.air){
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int i = ores.size - 1; i >= 0; i--){
|
||||
OreEntry entry = ores.get(i);
|
||||
if(entry.noise.octaveNoise2D(1, 0.7, 1f / (4 + i * 2), x, y) / 4f +
|
||||
Math.abs(0.5f - entry.noise.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), x, y)) > 0.48f &&
|
||||
Math.abs(0.5f - entry.noise.octaveNoise2D(1, 1, 1f / (55 + i * 4), x, y)) > 0.22f){
|
||||
tile.setFloor((Floor) OreBlocks.get(tile.floor(), entry.item));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateMap(Tile[][] tiles, int seed){
|
||||
int width = tiles.length, height = tiles[0].length;
|
||||
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
GenResult result = generateTile(0, 0, x, y);
|
||||
Tile tile = new Tile(x, y, (byte)result.floor.id, (byte)result.wall.id, (byte)0, (byte)0, result.elevation);
|
||||
tiles[x][y] = tile;
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
byte elevation = tile.elevation;
|
||||
|
||||
for(GridPoint2 point : Geometry.d4){
|
||||
if(!Mathf.inBounds(x + point.x, y + point.y, width, height)) continue;
|
||||
if(tiles[x + point.x][y + point.y].elevation < elevation){
|
||||
|
||||
if(Mathf.chance(0.05)){
|
||||
tile.elevation = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tiles[width / 2][height / 2].setBlock(StorageBlocks.core);
|
||||
tiles[width / 2][height / 2].setTeam(Team.blue);
|
||||
|
||||
prepareTiles(tiles, seed, true);
|
||||
}
|
||||
|
||||
public void setSector(int sectorX, int sectorY){
|
||||
random.setSeed(Bits.packLong(sectorX, sectorY));
|
||||
}
|
||||
|
||||
public GenResult generateTile(int sectorX, int sectorY, int localX, int localY){
|
||||
int x = sectorX * sectorSize + localX;
|
||||
int y = sectorY * sectorSize + localY;
|
||||
|
||||
Block floor = Blocks.stone;
|
||||
Block wall = Blocks.air;
|
||||
|
||||
double elevation = sim.octaveNoise2D(3, 0.5, 1f / 100, x, y) * 4.1 - 1;
|
||||
double temp = sim3.octaveNoise2D(7, 0.54, 1f / 320f, x, y);
|
||||
|
||||
double r = sim2.octaveNoise2D(1, 0.6, 1f / 70, x, y);
|
||||
double edgeDist = Math.max(sectorSize / 2, sectorSize / 2) - Math.max(Math.abs(x - sectorSize / 2), Math.abs(y - sectorSize / 2));
|
||||
double dst = Vector2.dst(sectorSize / 2, sectorSize / 2, x, y);
|
||||
double elevDip = 30;
|
||||
|
||||
double border = 14;
|
||||
|
||||
if(edgeDist < border){
|
||||
elevation += (border - edgeDist) / 6.0;
|
||||
}
|
||||
|
||||
if(temp < 0.35){
|
||||
floor = Blocks.snow;
|
||||
}else if(temp < 0.45){
|
||||
floor = Blocks.stone;
|
||||
}else if(temp < 0.65){
|
||||
floor = Blocks.grass;
|
||||
}else if(temp < 0.8){
|
||||
floor = Blocks.sand;
|
||||
}else if(temp < 0.9){
|
||||
floor = Blocks.blackstone;
|
||||
elevation = 0f;
|
||||
}else{
|
||||
floor = Blocks.lava;
|
||||
}
|
||||
|
||||
if(dst < elevDip){
|
||||
elevation -= (elevDip - dst) / elevDip * 3.0;
|
||||
}else if(r > 0.9){
|
||||
floor = Blocks.water;
|
||||
elevation = 0;
|
||||
|
||||
if(r > 0.94){
|
||||
floor = Blocks.deepwater;
|
||||
}
|
||||
}
|
||||
|
||||
if(wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){
|
||||
wall = decoration.get(floor);
|
||||
}
|
||||
|
||||
result.wall = wall;
|
||||
result.floor = floor;
|
||||
result.elevation = (byte) Math.max(elevation, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public class GenResult{
|
||||
public Block floor, wall;
|
||||
public byte elevation;
|
||||
}
|
||||
|
||||
public class OreEntry{
|
||||
final float frequency;
|
||||
final Item item;
|
||||
final Simplex noise;
|
||||
final RidgedPerlin ridge;
|
||||
final int index;
|
||||
|
||||
OreEntry(Item item, float frequency, int seed){
|
||||
this.frequency = frequency;
|
||||
this.item = item;
|
||||
this.noise = new Simplex(seed + oreIndex);
|
||||
this.ridge = new RidgedPerlin(seed + oreIndex, 2);
|
||||
this.index = oreIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user