elevation is gone but this time I'm not doing the crab rave meme
This commit is contained in:
@@ -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"),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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())){
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
core/src/io/anuke/mindustry/maps/generators/Generator.java
Normal file
14
core/src/io/anuke/mindustry/maps/generators/Generator.java
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public class LoadDialog extends FloatingDialog{
|
||||
hide();
|
||||
ui.paused.hide();
|
||||
|
||||
ui.loadLogic(() -> {
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
slot.load();
|
||||
state.set(State.playing);
|
||||
|
||||
@@ -100,7 +100,7 @@ public class PausedDialog extends FloatingDialog{
|
||||
return;
|
||||
}
|
||||
|
||||
ui.loadLogic("$saveload", () -> {
|
||||
ui.loadAnd("$saveload", () -> {
|
||||
try{
|
||||
control.saves.getCurrent().save();
|
||||
}catch(Throwable e){
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user