elevation is gone but this time I'm not doing the crab rave meme

This commit is contained in:
Anuken
2019-01-10 21:45:18 -05:00
parent 84e754dd10
commit ae3aa20508
28 changed files with 182 additions and 655 deletions

View File

@@ -57,10 +57,6 @@ public class Vars{
public static final float itemSize = 5f;
/**size of tiles in units*/
public static final int tilesize = 8;
/**size of sectors in tiles*/
public static final int sectorSize = 256;
/**specific number indicating 'invalid' sector*/
public static final int invalidSector = Integer.MAX_VALUE;
/**all choosable player colors in join/host dialog*/
public static final Color[] playerColors = {
Color.valueOf("82759a"),

View File

@@ -208,7 +208,7 @@ public class Control implements ApplicationListener{
}
public void playMap(Map map){
ui.loadLogic(() -> {
ui.loadAnd(() -> {
logic.reset();
world.loadMap(map);
logic.play();

View File

@@ -200,11 +200,11 @@ public class UI implements ApplicationListener{
generator.dispose();
}
public void loadGraphics(Runnable call){
loadGraphics("$loading", call);
public void loadAnd(Runnable call){
loadAnd("$loading", call);
}
public void loadGraphics(String text, Runnable call){
public void loadAnd(String text, Runnable call){
loadfrag.show(text);
Time.runTask(7f, () -> {
call.run();
@@ -212,19 +212,6 @@ public class UI implements ApplicationListener{
});
}
public void loadLogic(Runnable call){
loadLogic("$loading", call);
}
public void loadLogic(String text, Runnable call){
loadfrag.show(text);
Time.runTask(7f, () ->
Core.app.post(() -> {
call.run();
loadfrag.hide();
}));
}
public void showTextInput(String titleText, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
new Dialog(titleText, "dialog"){{
cont.margin(30).add(text).padRight(6f);

View File

@@ -4,8 +4,8 @@ import io.anuke.arc.ApplicationListener;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntArray;
import io.anuke.arc.entities.EntityQuery;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Structs;
@@ -20,18 +20,18 @@ import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.MapIO;
import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.mindustry.maps.Maps;
import io.anuke.mindustry.maps.WorldGenerator;
import io.anuke.mindustry.maps.generators.Generator;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
import static io.anuke.mindustry.Vars.*;
public class World implements ApplicationListener{
public final Maps maps = new Maps();
public final WorldGenerator generator = new WorldGenerator();
public final BlockIndexer indexer = new BlockIndexer();
public final WaveSpawner spawner = new WaveSpawner();
public final Pathfinder pathfinder = new Pathfinder();
@@ -172,10 +172,6 @@ public class World implements ApplicationListener{
Tile tile = tiles[x][y];
tile.updateOcclusion();
if(tile.floor() instanceof OreBlock && tile.hasCliffs()){
tile.setFloor(((OreBlock) tile.floor()).base);
}
if(tile.entity != null){
tile.entity.updateProximity();
}
@@ -192,6 +188,24 @@ public class World implements ApplicationListener{
return generating;
}
public void playGenerator(Generator generator){
ui.loadAnd(() -> {
logic.reset();
loadGenerator(generator);
logic.play();
});
}
public void loadGenerator(Generator generator){
beginMapLoad();
createTiles(generator.width, generator.height);
generator.generate(tiles);
prepareTiles(tiles);
endMapLoad();
}
public void loadMap(Map map){
beginMapLoad();
this.currentMap = map;
@@ -200,11 +214,9 @@ public class World implements ApplicationListener{
createTiles(width, height);
EntityQuery.resizeTree(0, 0, width * tilesize, height * tilesize);
try{
generator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), Mathf.random(99999));
} catch(Exception e){
loadTileData(tiles, MapIO.readTileData(map, true));
}catch(Exception e){
Log.err(e);
if(!headless){
ui.showError("$map.invalid");
@@ -370,6 +382,79 @@ public class World implements ApplicationListener{
}
}
/**Loads raw map tile data into a Tile[][] array, setting up multiblocks, cliffs and ores. */
void loadTileData(Tile[][] tiles, MapTileData data){
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);
}
}
prepareTiles(tiles);
}
/**'Prepares' a tile array by:<br>
* - setting up multiblocks<br>
* - updating occlusion<br>
* Usually used before placing structures on a tile array.*/
void prepareTiles(Tile[][] tiles){
//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];
if(tile.block().isMultiblock()){
multiblocks.add(tile.pos());
}
}
}
//place multiblocks now
for(int i = 0; i < multiblocks.size; i++){
int pos = multiblocks.get(i);
int x = Pos.x(pos);
int y = Pos.y(pos);
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();
}
}
}
public interface Raycaster{
boolean accept(int x, int y);
}

View File

@@ -86,7 +86,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
createDialog("$editor.import",
"$editor.importmap", "$editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show,
"$editor.importfile", "$editor.importfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$loadimage", "Map Files", file -> ui.loadGraphics(() -> {
Platform.instance.showFileChooser("$loadimage", "Map Files", file -> ui.loadAnd(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
@@ -103,7 +103,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
"$editor.importimage", "$editor.importimage.description", "icon-file-image", (Runnable)() ->
Platform.instance.showFileChooser("$loadimage", "Image Files", file ->
ui.loadGraphics(() -> {
ui.loadAnd(() -> {
try{
MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
@@ -121,7 +121,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Platform.instance.showFileChooser("$saveimage", "Map Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file;
ui.loadGraphics(() -> {
ui.loadAnd(() -> {
try{
if(!editor.getTags().containsKey("name")){
@@ -149,7 +149,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
ui.loadGraphics(() -> {
ui.loadAnd(() -> {
editor.resize(x, y);
view.clearStack();
});
@@ -157,7 +157,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
});
loadDialog = new MapLoadDialog(map ->
ui.loadGraphics(() -> {
ui.loadAnd(() -> {
try(DataInputStream stream = new DataInputStream(map.stream.get())){
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
@@ -291,7 +291,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
public void beginEditMap(InputStream is){
ui.loadGraphics(() -> {
ui.loadAnd(() -> {
try{
shownWithMap = true;
DataInputStream stream = new DataInputStream(is);
@@ -432,26 +432,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
t.add("$editor.brush");
t.row();
t.add(slider).width(size * 3f - 20).padTop(4f);
}).padTop(5).growX().growY().top();
mid.row();
mid.table("underline", t -> t.add("$editor.elevation"))
.colspan(3).height(40).width(size * 3f + 3f);
mid.row();
mid.table("underline", t -> {
t.margin(0);
t.addImageButton("icon-arrow-left", "clear-partial", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() - 1))
.disabled(b -> editor.getDrawElevation() <= -1).size(size);
t.label(() -> editor.getDrawElevation() == -1 ? "$editor.slope" : (editor.getDrawElevation() + ""))
.size(size).get().setAlignment(Align.center, Align.center);
t.addImageButton("icon-arrow-right", "clear-partial", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
.disabled(b -> editor.getDrawElevation() >= 63).size(size).name("aaaaa");
}).colspan(3).height(size).width(size * 3f + 3f);
}).padTop(5).growX().top();
}).margin(0).left().growY();

View File

@@ -6,11 +6,8 @@ import io.anuke.arc.collection.IntSet.IntSetIterator;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Disposable;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.IndexedRenderer;
import io.anuke.mindustry.maps.MapTileData.DataPosition;
@@ -106,7 +103,6 @@ public class MapRenderer implements Disposable{
byte bf = editor.getMap().read(wx, wy, DataPosition.floor);
byte bw = editor.getMap().read(wx, wy, DataPosition.wall);
byte btr = editor.getMap().read(wx, wy, DataPosition.rotationTeam);
byte elev = editor.getMap().read(wx, wy, DataPosition.elevation);
byte rotation = Pack.leftByte(btr);
Team team = Team.all[Pack.rightByte(btr)];
@@ -134,16 +130,9 @@ public class MapRenderer implements Disposable{
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
}
boolean check = checkElevation(elev, wx, wy);
if(wall.update || wall.destructible){
mesh.setColor(team.color);
region = Core.atlas.find("block-border");
}else if(elev > 0 && check){
mesh.setColor(tmpColor.fromHsv((360f * elev / 127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f));
region = Core.atlas.find("block-elevation");
}else if(elev == -1){
region = Core.atlas.find("block-slope");
}else{
region = Core.atlas.find("clear");
}
@@ -154,23 +143,6 @@ public class MapRenderer implements Disposable{
mesh.setColor(Color.WHITE);
}
private boolean checkElevation(byte elev, int x, int y){
for(Point2 p : Geometry.d4){
int wx = x + p.x, wy = y + p.y;
if(!Structs.inBounds(wx, wy, editor.getMap().width(), editor.getMap().height())){
return true;
}
byte value = editor.getMap().read(wx, wy, DataPosition.elevation);
if(value < elev){
return true;
}else if(value > elev){
delayedUpdates.add(wx + wy * width);
}
}
return false;
}
@Override
public void dispose(){
if(chunks == null){

View File

@@ -249,11 +249,6 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
if(tile.block() != Blocks.air){
onLiquid = false;
}
//on slope
if(tile.getElevation() == -1){
velocity.scl(0.7f);
}
}
if(onLiquid && velocity.len() > 0.4f && Mathf.chance((velocity.len() * floor.speedMultiplier) * 0.06f * Time.delta())){

View File

@@ -183,7 +183,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta();
for(Point2 point : Geometry.d4){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null && other.block() == Blocks.air && !other.hasCliffs()){
if(other != null && other.block() == Blocks.air){
deposit(other, tile, liquid, deposited, generation + 1);
amount -= deposited / 2f; //tweak to speed up/slow down puddle propagation
}

View File

@@ -125,7 +125,6 @@ public class Saves{
saveMap.put(slot.index, slot);
slot.meta = SaveIO.getData(slot.index);
current = slot;
slot.meta.sector = invalidSector;
saveSlots();
return slot;
}
@@ -176,7 +175,7 @@ public class Saves{
}
public boolean isHidden(){
return meta.sector != invalidSector;
return false;
}
public String getPlayTime(){

View File

@@ -135,7 +135,7 @@ public class MinimapRenderer implements Disposable{
private int colorFor(Tile tile){
tile = tile.target();
return ColorMapper.colorFor(tile.floor(), tile.block(), tile.getTeam(), tile.getElevation(), tile.getCliffs());
return ColorMapper.colorFor(tile.floor(), tile.block(), tile.getTeam());
}
@Override

View File

@@ -53,7 +53,7 @@ public class MapIO{
byte elev = y >= data.height() - 1 ? 0 : data.read(x, y + 1, DataPosition.elevation);
Block floor = content.block(marker.floor);
Block wall = content.block(marker.wall);
int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team], marker.elevation + 1, elev > marker.elevation ? (byte)(1 << 6) : (byte)0);
int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team]);
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color);
}
}

View File

@@ -33,12 +33,11 @@ public abstract class SaveFileVersion{
long time = stream.readLong();
long playtime = stream.readLong();
int build = stream.readInt();
int sector = stream.readInt();
byte mode = stream.readByte();
String map = stream.readUTF();
int wave = stream.readInt();
byte difficulty = stream.readByte();
return new SaveMeta(version, time, playtime, build, sector, mode, map, wave, Difficulty.values()[difficulty]);
return new SaveMeta(version, time, playtime, build, mode, map, wave, Difficulty.values()[difficulty]);
}
public void writeMap(DataOutputStream stream) throws IOException{
@@ -52,7 +51,6 @@ public abstract class SaveFileVersion{
stream.writeByte(tile.getFloorID());
stream.writeByte(tile.getBlockID());
stream.writeByte(tile.getElevation());
if(tile.block() instanceof BlockPart){
stream.writeByte(tile.link);
@@ -73,7 +71,7 @@ public abstract class SaveFileVersion{
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
Tile nextTile = world.tile(j % world.width(), j / world.width());
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air){
break;
}
@@ -98,10 +96,8 @@ public abstract class SaveFileVersion{
int x = i % width, y = i / width;
byte floorid = stream.readByte();
byte wallid = stream.readByte();
byte elevation = stream.readByte();
Tile tile = new Tile(x, y, floorid, wallid);
tile.setElevation(elevation);
if(wallid == Blocks.blockpart.id){
tile.link = stream.readByte();
@@ -135,7 +131,6 @@ public abstract class SaveFileVersion{
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
Tile newTile = new Tile(newx, newy, floorid, wallid);
newTile.setElevation(elevation);
tiles[newx][newy] = newTile;
}

View File

@@ -11,18 +11,16 @@ public class SaveMeta{
public int build;
public long timestamp;
public long timePlayed;
public int sector;
public GameMode mode;
public Map map;
public int wave;
public Difficulty difficulty;
public SaveMeta(int version, long timestamp, long timePlayed, int build, int sector, int mode, String map, int wave, Difficulty difficulty){
public SaveMeta(int version, long timestamp, long timePlayed, int build, int mode, String map, int wave, Difficulty difficulty){
this.version = version;
this.build = build;
this.timestamp = timestamp;
this.timePlayed = timePlayed;
this.sector = sector;
this.mode = GameMode.values()[mode];
this.map = world.maps.getByName(map);
this.wave = wave;

View File

@@ -1,374 +0,0 @@
package io.anuke.mindustry.maps;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntArray;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.RandomXS128;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Structs;
import io.anuke.arc.util.noise.RidgedPerlin;
import io.anuke.arc.util.noise.Simplex;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.OreBlock;
import static io.anuke.mindustry.Vars.*;
public class WorldGenerator{
private static final int baseSeed = 0;
private int oreIndex = 0;
private Simplex sim = new Simplex(baseSeed);
private Simplex sim2 = new Simplex(baseSeed + 1);
private Simplex sim3 = new Simplex(baseSeed + 2);
private RidgedPerlin rid = new RidgedPerlin(baseSeed + 4, 1);
private RandomXS128 random = new RandomXS128(baseSeed + 3);
private GenResult result = new GenResult();
private ObjectMap<Block, Block> decoration;
public WorldGenerator(){
decoration = ObjectMap.of(
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);
generateOres(tiles, seed, genOres, null);
}
/**'Prepares' a tile array by:<br>
* - setting up multiblocks<br>
* - updating cliff data<br>
* - removing ores on cliffs<br>
* Usually used before placing structures on a tile array.*/
public void prepareTiles(Tile[][] tiles){
//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];
if(tile.block().isMultiblock()){
multiblocks.add(tile.pos());
}
}
}
//place multiblocks now
for(int i = 0; i < multiblocks.size; i++){
int pos = multiblocks.get(i);
int x = Pos.x(pos);
int y = Pos.y(pos);
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.hasCliffs() && !tile.block().isMultiblock() && tile.block() != Blocks.blockpart){
tile.setBlock(Blocks.air);
}
//remove ore veins on cliffs
if(tile.floor() instanceof OreBlock && tile.hasCliffs()){
tile.setFloor(((OreBlock)tile.floor()).base);
}
}
}
}
public void playRandomMap(){
ui.loadLogic(() -> {
logic.reset();
int sx = (short)Mathf.range(Short.MAX_VALUE/2);
int sy = (short)Mathf.range(Short.MAX_VALUE/2);
int width = 256;
int height = 256;
Array<Point2> spawns = new Array<>();
Array<Item> ores = Item.getAllOres();
if(state.mode.isPvp){
int scaling = 10;
spawns.add(new Point2(width/scaling, height/scaling));
spawns.add(new Point2(width - 1 - width/scaling, height - 1 - height/scaling));
}else{
spawns.add(new Point2(width/2, height/2));
}
Tile[][] tiles = world.createTiles(width, height);
world.setMap(new Map("Generated Map", width, height));
world.beginMapLoad();
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
generateTile(result, sx, sy, x, y, true, spawns, ores);
tiles[x][y] = new Tile(x, y, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation);
}
}
prepareTiles(tiles);
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
Tile tile = tiles[x][y];
byte elevation = tile.getElevation();
for(Point2 point : Geometry.d4){
if(!Structs.inBounds(x + point.x, y + point.y, width, height)) continue;
if(tiles[x + point.x][y + point.y].getElevation() < elevation){
if(sim2.octaveNoise2D(1, 1, 1.0 / 8, x, y) > 0.8){
tile.setElevation(-1);
}
break;
}
}
}
}
world.setBlock(tiles[spawns.get(0).x][spawns.get(0).y], Blocks.core, Team.blue);
world.setBlock(tiles[spawns.get(0).x][spawns.get(0).y - 3], Blocks.launchPad, Team.blue);
if(state.mode.isPvp){
world.setBlock(tiles[spawns.get(1).x][spawns.get(1).y], Blocks.core, Team.red);
}
world.endMapLoad();
logic.play();
});
}
public void generateOres(Tile[][] tiles, long seed, boolean genOres, Array<Item> usedOres){
oreIndex = 0;
if(genOres){
Array<OreEntry> baseOres = Array.with(
new OreEntry(Items.copper, 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)
);
Array<OreEntry> ores = new Array<>();
if(usedOres == null){
ores.addAll(baseOres);
}else{
for(Item item : usedOres){
ores.add(baseOres.find(entry -> entry.item == item));
}
}
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.hasCliffs() || 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) OreBlock.get(tile.floor(), entry.item));
break;
}
}
}
}
}
}
public GenResult generateTile(int sectorX, int sectorY, int localX, int localY){
return generateTile(sectorX, sectorY, localX, localY, true);
}
public GenResult generateTile(int sectorX, int sectorY, int localX, int localY, boolean detailed){
return generateTile(result, sectorX, sectorY, localX, localY, detailed, null, null);
}
/**
* Gets the generation result from a specific sector at specific coordinates.
* @param result where to put the generation results
* @param sectorX X of the sector in terms of sector coordinates
* @param sectorY Y of the sector in terms of sector coordinates
* @param localX X in terms of local sector tile coordinates
* @param localY Y in terms of local sector tile coordinates
* @param detailed whether the tile result is 'detailed' (e.g. previews should not be detailed)
* @param spawnpoints list of player spawnpoints, can be null
* @return the GenResult passed in with its values modified
*/
public GenResult generateTile(GenResult result, int sectorX, int sectorY, int localX, int localY, boolean detailed, Array<Point2> spawnpoints, Array<Item> ores){
int x = sectorX * sectorSize + localX + Short.MAX_VALUE;
int y = sectorY * sectorSize + localY + Short.MAX_VALUE;
Block floor;
Block wall = Blocks.air;
double ridge = rid.getValue(x, y, 1f / 400f);
double iceridge = rid.getValue(x+99999, y, 1f / 300f) + sim3.octaveNoise2D(2, 1f, 1f/14f, x, y)/11f;
double elevation = elevationOf(x, y, detailed);
double temp =
+ sim3.octaveNoise2D(detailed ? 12 : 9, 0.6, 1f / 1100f, x - 120, y);
double lake = sim2.octaveNoise2D(1, 1, 1f / 110f, x, y);
elevation -= Math.pow(lake + 0.15, 5);
int lerpDst = 20;
lerpDst *= lerpDst;
float minDst = Float.MAX_VALUE;
if(detailed && spawnpoints != null){
for(Point2 p : spawnpoints){
float dst = Mathf.dst2(p.x, p.y, localX, localY);
minDst = Math.min(minDst, dst);
if(dst < lerpDst){
float targetElevation = Math.max(0.86f, (float)elevationOf(sectorX * sectorSize + p.x + Short.MAX_VALUE, sectorY * sectorSize + p.y + Short.MAX_VALUE, true));
elevation = Mathf.lerp((float)elevation, targetElevation, Mathf.clamp(1.5f*(1f-(dst / lerpDst))));
}
}
}
if(elevation < 0.7){
floor = Blocks.deepwater;
}else if(elevation < 0.79){
floor = Blocks.water;
}else if(elevation < 0.85){
floor = Blocks.sand;
}else if (elevation < 2.5 && temp > 0.5){
floor = Blocks.sand;
}else if(temp < 0.42){
floor = Blocks.snow;
}else if(temp < 0.5){
floor = Blocks.stone;
}else if(temp < 0.6){
floor = Blocks.grass;
}else if(temp + ridge/2f < 0.8 || elevation < 1.3){
floor = Blocks.blackstone;
if(iceridge > 0.25 && minDst > lerpDst/1.5f){
elevation ++;
}
}else{
floor = Blocks.blackstone;
}
if(elevation > 3.3 && iceridge > 0.25 && temp < 0.6f){
elevation ++;
floor = Blocks.ice;
}
if(((Floor)floor).liquidDrop != null){
elevation = 0;
}
if(detailed && wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){
wall = decoration.get(floor);
}
if(ores != null && ((Floor) floor).hasOres){
int offsetX = x - 4, offsetY = y + 23;
for(int i = ores.size - 1; i >= 0; i--){
Item entry = ores.get(i);
if(Math.abs(0.5f - sim.octaveNoise2D(2, 0.7, 1f / (50 + i * 2), offsetX, offsetY)) > 0.23f &&
Math.abs(0.5f - sim2.octaveNoise2D(1, 1, 1f / (40 + i * 4), offsetX, offsetY)) > 0.32f){
floor = OreBlock.get(floor, entry);
break;
}
}
}
result.wall = wall;
result.floor = floor;
result.elevation = (byte) Math.max(elevation, 0);
return result;
}
double elevationOf(int x, int y, boolean detailed){
double ridge = rid.getValue(x, y, 1f / 400f);
return sim.octaveNoise2D(detailed ? 7 : 5, 0.62, 1f / 800, x, y) * 6.1 - 1 - ridge;
}
public static 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, long seed){
this.frequency = frequency;
this.item = item;
this.noise = new Simplex(seed + oreIndex);
this.ridge = new RidgedPerlin((int)(seed + oreIndex), 2);
this.index = oreIndex++;
}
}
}

View File

@@ -0,0 +1,14 @@
package io.anuke.mindustry.maps.generators;
import io.anuke.mindustry.world.Tile;
public abstract class Generator{
public final int width, height;
public Generator(int width, int height){
this.width = width;
this.height = height;
}
public abstract void generate(Tile[][] tiles);
}

View File

@@ -0,0 +1,33 @@
package io.anuke.mindustry.maps.generators;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
public abstract class RandomGenerator extends Generator{
protected Block floor;
protected Block block;
public RandomGenerator(int width, int height, Block floor){
super(width, height);
this.floor = floor;
}
@Override
public void generate(Tile[][] tiles){
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
floor = Blocks.air;
block = Blocks.air;
generate(x, y);
tiles[x][y].setFloor((Floor) floor);
tiles[x][y].setBlock(block);
}
}
}
/**Sets {@link #floor} and {@link #block} to the correct values as output.
* Before this method is called, both are set to {@link Blocks#air} as defaults.*/
public abstract void generate(int x, int y);
}

View File

@@ -58,7 +58,6 @@ public class NetworkIO{
stream.writeByte(tile.getFloorID());
stream.writeByte(tile.getBlockID());
stream.writeByte(tile.getElevation());
if(tile.block() instanceof BlockPart){
stream.writeByte(tile.link);
@@ -79,7 +78,7 @@ public class NetworkIO{
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
Tile nextTile = world.tile(j % world.width(), j / world.width());
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air){
break;
}
@@ -165,10 +164,8 @@ public class NetworkIO{
int x = i % width, y = i / width;
byte floorid = stream.readByte();
byte wallid = stream.readByte();
byte elevation = stream.readByte();
Tile tile = new Tile(x, y, floorid, wallid);
tile.setElevation(elevation);
if(wallid == Blocks.blockpart.id){
tile.link = stream.readByte();
@@ -196,7 +193,6 @@ public class NetworkIO{
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
Tile newTile = new Tile(newx, newy, floorid, wallid);
newTile.setElevation(elevation);
tiles[newx][newy] = newTile;
}

View File

@@ -4,10 +4,12 @@ import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.maps.generators.Generator;
public class Zone extends UnlockableContent{
public final String name;
public ItemStack[] deployCost = {};
public Generator generator;
public Zone(String name){
this.name = name;

View File

@@ -118,12 +118,13 @@ public class CustomGameDialog extends FloatingDialog{
i++;
}
/*
ImageButton gen = maps.addImageButton("icon-editor", "clear", 16*4, () -> {
hide();
world.generator.playRandomMap();
}).growY().get();
gen.row();
gen.add("$map.random");
gen.add("$map.random");*/
if(world.maps.all().size == 0){
maps.add("$maps.none").pad(50);

View File

@@ -8,7 +8,7 @@ import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.ItemType;
import io.anuke.mindustry.type.Zone;
import static io.anuke.mindustry.Vars.data;
import static io.anuke.mindustry.Vars.*;
public class DeployDialog extends FloatingDialog{
@@ -45,7 +45,7 @@ public class DeployDialog extends FloatingDialog{
t.addButton(zone.localizedName(), () -> {
data.removeItems(zone.deployCost);
hide();
Vars.world.generator.playRandomMap();
world.playGenerator(zone.generator);
}).size(150f).disabled(b -> !data.hasItems(zone.deployCost));
t.row();
t.table(req -> {

View File

@@ -1,107 +0,0 @@
package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.Core;
import io.anuke.arc.Graphics.Cursor.SystemCursor;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.GridMap;
import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.graphics.Pixmap.Format;
import io.anuke.arc.graphics.Texture;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.input.KeyCode;
import io.anuke.arc.scene.Element;
import io.anuke.arc.scene.event.InputEvent;
import io.anuke.arc.scene.event.InputListener;
import io.anuke.arc.util.async.AsyncExecutor;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.maps.WorldGenerator.GenResult;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.ColorMapper;
import static io.anuke.mindustry.Vars.sectorSize;
import static io.anuke.mindustry.Vars.world;
public class GenViewDialog extends FloatingDialog{
Array<Item> ores = Array.with(Items.copper, Items.lead, Items.coal);
public GenViewDialog(){
super("generate view");
cont.add(new GenView()).grow();
}
public class GenView extends Element{
GridMap<Texture> map = new GridMap<>();
GridMap<Boolean> processing = new GridMap<>();
float panX, panY;
float lastX, lastY;
int viewsize = 3;
AsyncExecutor async = new AsyncExecutor(viewsize*2 * viewsize*2);
{
addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
Core.graphics.cursor(SystemCursor.hand);
lastX = x;
lastY = y;
return true;
}
@Override
public void touchDragged(InputEvent event, float x, float y, int pointer){
panX -= x - lastX;
panY -= y - lastY;
lastX = x;
lastY = y;
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){
Core.graphics.restoreCursor();
}
});
}
public void draw(){
float padSectorSize = 200f;
int tx = (int)(panX / padSectorSize);
int ty = (int)(panY / padSectorSize);
Draw.color();
for(int x = -viewsize; x <= viewsize; x++){
for(int y = -viewsize; y <= viewsize; y++){
int wx = tx + x, wy = ty + y;
if(map.get(wx, wy) == null){
if(processing.get(wx, wy) == Boolean.TRUE){
continue;
}
processing.put(wx, wy, true);
async.submit(() -> {
GenResult result = new GenResult();
Pixmap pixmap = new Pixmap(sectorSize, sectorSize, Format.RGBA8888);
for(int i = 0; i < sectorSize; i++){
for(int j = 0; j < sectorSize; j++){
world.generator.generateTile(result, wx, wy, i, j, true, null, ores);
pixmap.drawPixel(i, sectorSize - 1 - j, ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, (byte)0));
}
}
Core.app.post(() -> map.put(wx, wy, new Texture(pixmap)));
return pixmap;
});
continue;
}
float drawX = x + width/2f+ wx * padSectorSize - tx * padSectorSize - panX % padSectorSize;
float drawY = y + height/2f + wy * padSectorSize - ty * padSectorSize - panY % padSectorSize;
Draw.rect(Draw.wrap(map.get(wx, wy)), drawX + padSectorSize/2f, drawY + padSectorSize/2f, padSectorSize, padSectorSize);
}
}
}
}
}

View File

@@ -173,7 +173,7 @@ public class LoadDialog extends FloatingDialog{
hide();
ui.paused.hide();
ui.loadLogic(() -> {
ui.loadAnd(() -> {
try{
slot.load();
state.set(State.playing);

View File

@@ -100,7 +100,7 @@ public class PausedDialog extends FloatingDialog{
return;
}
ui.loadLogic("$saveload", () -> {
ui.loadAnd("$saveload", () -> {
try{
control.saves.getCurrent().save();
}catch(Throwable e){

View File

@@ -24,7 +24,7 @@ public class SaveDialog extends LoadDialog{
slots.row();
slots.addImageTextButton("$save.new", "icon-add",14 * 3, () ->
ui.showTextInput("$save", "$save.newslot", "", text -> {
ui.loadGraphics("$saving", () -> {
ui.loadAnd("$saving", () -> {
control.saves.addSave(text);
Core.app.post(() -> Core.app.post(this::setup));
});

View File

@@ -60,7 +60,7 @@ public class MenuFragment extends Fragment{
maps = new MobileButton("icon-map", isize, "$maps", ui.maps::show),
load = new MobileButton("icon-load", isize, "$load", ui.load::show),
join = new MobileButton("icon-add", isize, "$joingame", ui.join::show),
editor = new MobileButton("icon-editor", isize, "$editor", () -> ui.loadGraphics(ui.editor::show)),
editor = new MobileButton("icon-editor", isize, "$editor", () -> ui.loadAnd(ui.editor::show)),
tools = new MobileButton("icon-tools", isize, "$settings", ui.settings::show),
unlocks = new MobileButton("icon-unlocks", isize, "$unlocks", ui.unlocks::show),
donate = new MobileButton("icon-donate", isize, "$donate", Platform.instance::openDonations);
@@ -115,7 +115,7 @@ public class MenuFragment extends Fragment{
out.row();
out.add(new MenuButton("icon-editor", "$editor", () -> ui.loadGraphics(ui.editor::show)));
out.add(new MenuButton("icon-editor", "$editor", () -> ui.loadAnd(ui.editor::show)));
out.add(new MenuButton("icon-map", "$maps", ui.maps::show));

View File

@@ -149,8 +149,8 @@ public class Build{
for(int dx = 0; dx < type.size; dx++){
for(int dy = 0; dy < type.size; dy++){
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace)
|| other.hasCliffs() || !other.floor().placeableOn ||
if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) ||
!other.floor().placeableOn ||
(other.floor().isLiquid && !type.floating)){
return false;
}
@@ -161,7 +161,7 @@ public class Build{
return (tile.getTeam() == Team.none || tile.getTeam() == team)
&& contactsGround(tile.x, tile.y, type)
&& (!tile.floor().isLiquid || type.floating)
&& tile.floor().placeableOn && !tile.hasCliffs()
&& tile.floor().placeableOn
&& ((type.canReplace(tile.block())
&& !(type == tile.block() && rotation == tile.getRotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air)
&& tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile);

View File

@@ -17,24 +17,12 @@ public class ColorMapper implements ContentList{
return colorMap.get(block, 0);
}
public static int colorFor(Block floor, Block wall, Team team, int elevation, byte cliffs){
public static int colorFor(Block floor, Block wall, Team team){
if(wall.synthetic()){
return team.intColor;
}
int color = getBlockColor(wall);
if(color == 0) color = ColorMapper.getBlockColor(floor);
if(elevation > 0){
if(tmpColors.get() == null) tmpColors.set(new Color());
Color tmpColor = tmpColors.get();
tmpColor.set(color);
float maxMult = 1f/Math.max(Math.max(tmpColor.r, tmpColor.g), tmpColor.b) ;
float mul = Math.min(0.7f + elevation / 5f, maxMult);
if((cliffs & ((1 << 6))) != 0){
mul -= 0.35f;
}
tmpColor.mul(mul, mul, mul, 1f);
color = Color.rgba8888(tmpColor);
}
return color;
}

View File

@@ -32,16 +32,12 @@ public class Tile implements Position, TargetTrait{
/** Tile entity, usually null. */
public TileEntity entity;
public short x, y;
/** Position of cliffs around the tile, packed into bits 0-8. */
private byte cliffs;
private Block wall;
private Floor floor;
/** Rotation, 0-3. Also used to store offload location, in which case it can be any number. */
private byte rotation;
/** Team ordinal. */
private byte team;
/** Tile elevation. -1 means slope.*/
private byte elevation;
public Tile(int x, int y){
this.x = (short) x;
@@ -55,12 +51,11 @@ public class Tile implements Position, TargetTrait{
changed();
}
public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team, byte elevation){
public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team){
this(x, y);
this.floor = (Floor) content.block(floor);
this.wall = content.block(wall);
this.rotation = rotation;
this.setElevation(elevation);
changed();
this.team = team;
}
@@ -181,26 +176,6 @@ public class Tile implements Position, TargetTrait{
this.rotation = dump;
}
public byte getElevation(){
return elevation;
}
public void setElevation(int elevation){
this.elevation = (byte)elevation;
}
public byte getCliffs(){
return cliffs;
}
public void setCliffs(byte cliffs){
this.cliffs = cliffs;
}
public boolean hasCliffs(){
return getCliffs() != 0;
}
public boolean passable(){
Block block = block();
Block floor = floor();
@@ -216,7 +191,7 @@ public class Tile implements Position, TargetTrait{
public boolean solid(){
Block block = block();
Block floor = floor();
return block.solid || getCliffs() != 0 || (floor.solid && (block == Blocks.air || block.solidifes)) || block.isSolidFor(this)
return block.solid || (floor.solid && (block == Blocks.air || block.solidifes)) || block.isSolidFor(this)
|| (isLinked() && getLinked().block().isSolidFor(getLinked()));
}
@@ -338,7 +313,6 @@ public class Tile implements Position, TargetTrait{
public void updateOcclusion(){
cost = 1;
cliffs = 0;
boolean occluded = false;
//check for occlusion
@@ -351,16 +325,6 @@ public class Tile implements Position, TargetTrait{
}
}
//check for bitmasking cliffs
for(int i = 0; i < 4; i++){
Tile tc = getNearby(i);
//check for cardinal direction elevation changes and bitmask that
if(tc != null && ((tc.elevation < elevation && tc.elevation != -1))){
cliffs |= (1 << (i * 2));
}
}
if(occluded){
cost += 1;
}
@@ -436,6 +400,7 @@ public class Tile implements Position, TargetTrait{
@Override
public void setX(float x){
throw new IllegalArgumentException("Tile position cannot change.");
}
@Override
@@ -445,6 +410,7 @@ public class Tile implements Position, TargetTrait{
@Override
public void setY(float y){
throw new IllegalArgumentException("Tile position cannot change.");
}
@Override