wow it builds
This commit is contained in:
@@ -9,6 +9,7 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.content;
|
import static io.anuke.mindustry.Vars.content;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class DrawOperation{
|
public class DrawOperation{
|
||||||
private LongArray array = new LongArray();
|
private LongArray array = new LongArray();
|
||||||
@@ -24,32 +25,46 @@ public class DrawOperation{
|
|||||||
public void undo(MapEditor editor){
|
public void undo(MapEditor editor){
|
||||||
for(int i = array.size - 1; i >= 0; i--){
|
for(int i = array.size - 1; i >= 0; i--){
|
||||||
long l = array.get(i);
|
long l = array.get(i);
|
||||||
set(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.from(l));
|
array.set(i, TileOp.value(l, get(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l))));
|
||||||
|
set(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.value(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redo(MapEditor editor){
|
public void redo(MapEditor editor){
|
||||||
for(int i = 0; i < array.size; i++){
|
for(int i = 0; i < array.size; i++){
|
||||||
long l = array.get(i);
|
long l = array.get(i);
|
||||||
set(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.to(l));
|
array.set(i, TileOp.value(l, get(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l))));
|
||||||
|
set(editor, editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.value(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(MapEditor editor, Tile tile, byte type, byte to){
|
short get(MapEditor editor, Tile tile, byte type){
|
||||||
|
if(type == OpType.floor.ordinal()){
|
||||||
|
return tile.floorID();
|
||||||
|
}else if(type == OpType.block.ordinal()){
|
||||||
|
return tile.blockID();
|
||||||
|
}else if(type == OpType.rotation.ordinal()){
|
||||||
|
return tile.rotation();
|
||||||
|
}else if(type == OpType.team.ordinal()){
|
||||||
|
return tile.getTeamID();
|
||||||
|
}else if(type == OpType.overlay.ordinal()){
|
||||||
|
return tile.overlayID();
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(MapEditor editor, Tile tile, byte type, short to){
|
||||||
editor.load(() -> {
|
editor.load(() -> {
|
||||||
if(type == OpType.floor.ordinal()){
|
if(type == OpType.floor.ordinal()){
|
||||||
tile.setFloor((Floor)content.block(to));
|
tile.setFloor((Floor)content.block(to));
|
||||||
}else if(type == OpType.block.ordinal()){
|
}else if(type == OpType.block.ordinal()){
|
||||||
Block block = content.block(to);
|
Block block = content.block(to);
|
||||||
tile.setBlock(block);
|
world.setBlock(tile, block, tile.getTeam(), tile.rotation());
|
||||||
if(block.isMultiblock()){
|
|
||||||
editor.updateLinks(block, tile.x, tile.y);
|
|
||||||
}
|
|
||||||
}else if(type == OpType.rotation.ordinal()){
|
}else if(type == OpType.rotation.ordinal()){
|
||||||
tile.rotation(to);
|
tile.rotation(to);
|
||||||
}else if(type == OpType.team.ordinal()){
|
}else if(type == OpType.team.ordinal()){
|
||||||
tile.setTeam(Team.all[to]);
|
tile.setTeam(Team.all[to]);
|
||||||
}else if(type == OpType.ore.ordinal()){
|
}else if(type == OpType.overlay.ordinal()){
|
||||||
tile.setOverlayID(to);
|
tile.setOverlayID(to);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -60,8 +75,8 @@ public class DrawOperation{
|
|||||||
class TileOpStruct{
|
class TileOpStruct{
|
||||||
short x;
|
short x;
|
||||||
short y;
|
short y;
|
||||||
short value;
|
|
||||||
byte type;
|
byte type;
|
||||||
|
short value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OpType{
|
public enum OpType{
|
||||||
@@ -69,6 +84,6 @@ public class DrawOperation{
|
|||||||
block,
|
block,
|
||||||
rotation,
|
rotation,
|
||||||
team,
|
team,
|
||||||
ore
|
overlay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,54 +33,43 @@ public class EditorTile extends Tile{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block previous = floor();
|
if(floor == type && overlayID() == 0) return;
|
||||||
Block ore = overlay();
|
if(overlayID() != 0) op(OpType.overlay, overlayID());
|
||||||
if(previous == type && ore == Blocks.air) return;
|
if(floor != type) op(OpType.floor, floor.id);
|
||||||
super.setFloor(type);
|
super.setFloor(type);
|
||||||
//ore may get nullified so make sure to save edits
|
|
||||||
if(overlay() != ore){
|
|
||||||
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, overlay().id));
|
|
||||||
}
|
|
||||||
if(previous != type){
|
|
||||||
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(Block type){
|
public void setBlock(Block type){
|
||||||
Block previous = block;
|
if(block == type) return;
|
||||||
byte pteam = getTeamID();
|
op(OpType.block, block.id);
|
||||||
if(previous == type) return;
|
|
||||||
super.setBlock(type);
|
super.setBlock(type);
|
||||||
if(pteam != getTeamID()){
|
|
||||||
op(TileOp.get(x, y, (byte)OpType.team.ordinal(), pteam, getTeamID()));
|
|
||||||
}
|
|
||||||
op(TileOp.get(x, y, (byte)OpType.block.ordinal(), previous.id, type.id));
|
|
||||||
|
|
||||||
|
//TODO check if this line is necessary
|
||||||
|
//if(pteam != getTeamID()){
|
||||||
|
// op((byte)OpType.team.ordinal(), pteam, getTeamID());
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTeam(Team team){
|
public void setTeam(Team team){
|
||||||
byte previous = getTeamID();
|
if(getTeamID() == team.ordinal()) return;
|
||||||
if(previous == team.ordinal()) return;
|
op(OpType.team, getTeamID());
|
||||||
super.setTeam(team);
|
super.setTeam(team);
|
||||||
op(TileOp.get(x, y, (byte)OpType.team.ordinal(), previous, (byte)team.ordinal()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rotation(byte rotation){
|
public void rotation(int rotation){
|
||||||
byte previous = rotation();
|
if(rotation == rotation()) return;
|
||||||
if(previous == rotation) return;
|
op(OpType.rotation, rotation());
|
||||||
super.rotation(rotation);
|
super.rotation(rotation);
|
||||||
op(TileOp.get(x, y, (byte)OpType.rotation.ordinal(), previous, rotation));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOverlayID(byte ore){
|
public void setOverlayID(short overlay){
|
||||||
byte previous = overlayID();
|
if(overlayID() == overlay) return;
|
||||||
if(previous == ore) return;
|
op(OpType.overlay, overlay);
|
||||||
super.setOverlayID(ore);
|
super.setOverlayID(overlay);
|
||||||
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), previous, ore));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,7 +101,7 @@ public class EditorTile extends Tile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void op(long op){
|
private void op(OpType type, short value){
|
||||||
ui.editor.editor.addTileOp(op);
|
ui.editor.editor.addTileOp(TileOp.get(x, y, (byte)type.ordinal(), value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,7 @@ public enum EditorTool{
|
|||||||
public void touched(MapEditor editor, int x, int y){
|
public void touched(MapEditor editor, int x, int y){
|
||||||
if(!Structs.inBounds(x, y, editor.width(), editor.height())) return;
|
if(!Structs.inBounds(x, y, editor.width(), editor.height())) return;
|
||||||
|
|
||||||
Tile tile = editor.tile(x, y);
|
Tile tile = editor.tile(x, y).link();
|
||||||
|
|
||||||
byte link = tile.getLinkByte();
|
|
||||||
|
|
||||||
if(tile.isLinked()){
|
|
||||||
x -= (Pack.leftByte(link) - 8);
|
|
||||||
y -= (Pack.rightByte(link) - 8);
|
|
||||||
|
|
||||||
tile = editor.tile(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//do not.
|
|
||||||
if(tile.isLinked()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.drawBlock = tile.block() == Blocks.air ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
|
editor.drawBlock = tile.block() == Blocks.air ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
|
||||||
}
|
}
|
||||||
@@ -87,7 +73,7 @@ public enum EditorTool{
|
|||||||
Block draw = editor.drawBlock;
|
Block draw = editor.drawBlock;
|
||||||
dest = draw instanceof OverlayFloor ? tile.overlay() : isfloor ? floor : block;
|
dest = draw instanceof OverlayFloor ? tile.overlay() : isfloor ? floor : block;
|
||||||
|
|
||||||
if(dest == draw || block == Blocks.part || block.isMultiblock()){
|
if(dest == draw || block instanceof BlockPart || block.isMultiblock()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.anuke.mindustry.editor;
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
|
||||||
import io.anuke.arc.collection.StringMap;
|
import io.anuke.arc.collection.StringMap;
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.graphics.Pixmap;
|
import io.anuke.arc.graphics.Pixmap;
|
||||||
@@ -110,7 +109,7 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map createMap(FileHandle file){
|
public Map createMap(FileHandle file){
|
||||||
return new Map(file, width(), height(), new ObjectMap<>(tags), true);
|
return new Map(file, width(), height(), new StringMap(tags), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reset(){
|
private void reset(){
|
||||||
|
|||||||
@@ -19,13 +19,11 @@ import io.anuke.arc.util.*;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.Platform;
|
import io.anuke.mindustry.core.Platform;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.LegacyMapIO;
|
|
||||||
import io.anuke.mindustry.io.MapIO;
|
import io.anuke.mindustry.io.MapIO;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.Map;
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Block.Icon;
|
import io.anuke.mindustry.world.Block.Icon;
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.OverlayFloor;
|
import io.anuke.mindustry.world.blocks.OverlayFloor;
|
||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
||||||
|
|
||||||
@@ -122,7 +120,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
if(!editor.getTags().containsKey("name")){
|
if(!editor.getTags().containsKey("name")){
|
||||||
editor.getTags().put("name", result.nameWithoutExtension());
|
editor.getTags().put("name", result.nameWithoutExtension());
|
||||||
}
|
}
|
||||||
MapIO.writeMap(result, editor.createMap(result), editor.tiles());
|
MapIO.writeMap(result, editor.createMap(result));
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, false)));
|
ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, false)));
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
|
|||||||
@@ -322,7 +322,8 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class DummyTile{
|
public static class DummyTile{
|
||||||
public byte block, floor, ore, team, rotation;
|
public byte team, rotation;
|
||||||
|
public short block, floor, ore;
|
||||||
|
|
||||||
void set(Block floor, Block wall, Block ore, Team team, int rotation){
|
void set(Block floor, Block wall, Block ore, Team team, int rotation){
|
||||||
this.floor = floor.id;
|
this.floor = floor.id;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.StringMap;
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.graphics.Color;
|
import io.anuke.arc.graphics.Color;
|
||||||
import io.anuke.arc.graphics.Pixmap;
|
import io.anuke.arc.graphics.Pixmap;
|
||||||
@@ -27,7 +27,7 @@ public class LegacyMapIO{
|
|||||||
|
|
||||||
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
||||||
try(DataInputStream stream = new DataInputStream(file.read(1024))){
|
try(DataInputStream stream = new DataInputStream(file.read(1024))){
|
||||||
ObjectMap<String, String> tags = new ObjectMap<>();
|
StringMap tags = new StringMap();
|
||||||
|
|
||||||
//meta is uncompressed
|
//meta is uncompressed
|
||||||
int version = stream.readInt();
|
int version = stream.readInt();
|
||||||
@@ -107,7 +107,12 @@ public class LegacyMapIO{
|
|||||||
Block block = content.block(stream.readByte());
|
Block block = content.block(stream.readByte());
|
||||||
|
|
||||||
Tile tile = tiles.get(x, y);
|
Tile tile = tiles.get(x, y);
|
||||||
tile.setBlock(block);
|
//the spawn block is saved in the block tile layer in older maps, shift it to the overlay
|
||||||
|
if(block != Blocks.spawn){
|
||||||
|
tile.setBlock(block);
|
||||||
|
}else{
|
||||||
|
tile.setOverlay(block);
|
||||||
|
}
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.entity != null){
|
||||||
byte tr = stream.readByte();
|
byte tr = stream.readByte();
|
||||||
|
|||||||
@@ -49,9 +49,10 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void writeMap(FileHandle file, Map map) throws IOException{
|
public static void writeMap(FileHandle file, Map map) throws IOException{
|
||||||
SaveIO.write(file);
|
try{
|
||||||
try(DataOutputStream out = new DataOutputStream(file.write(false, bufferSize))){
|
SaveIO.write(file, map.tags);
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.IntMap;
|
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.util.io.CounterInputStream;
|
import io.anuke.arc.util.io.CounterInputStream;
|
||||||
import io.anuke.arc.util.io.FastDeflaterOutputStream;
|
import io.anuke.arc.util.io.FastDeflaterOutputStream;
|
||||||
@@ -100,18 +99,26 @@ public class SaveIO{
|
|||||||
return file.sibling(file.name() + "-backup." + file.extension());
|
return file.sibling(file.name() + "-backup." + file.extension());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(FileHandle file){
|
public static void write(FileHandle file, StringMap tags){
|
||||||
write(new FastDeflaterOutputStream(file.write(false, bufferSize)));
|
write(new FastDeflaterOutputStream(file.write(false, bufferSize)), tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(OutputStream os){
|
public static void write(FileHandle file){
|
||||||
|
write(file, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(OutputStream os, StringMap tags){
|
||||||
DataOutputStream stream;
|
DataOutputStream stream;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
stream = new DataOutputStream(os);
|
stream = new DataOutputStream(os);
|
||||||
stream.write(header);
|
stream.write(header);
|
||||||
stream.writeInt(getVersion().version);
|
stream.writeInt(getVersion().version);
|
||||||
getVersion().write(stream);
|
if(tags == null){
|
||||||
|
getVersion().write(stream);
|
||||||
|
}else{
|
||||||
|
getVersion().write(stream, tags);
|
||||||
|
}
|
||||||
stream.close();
|
stream.close();
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.StringMap;
|
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
import io.anuke.arc.util.io.CounterInputStream;
|
import io.anuke.arc.util.io.CounterInputStream;
|
||||||
import io.anuke.mindustry.entities.Entities;
|
import io.anuke.mindustry.entities.Entities;
|
||||||
@@ -31,10 +30,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void write(DataOutputStream stream) throws IOException{
|
public final void write(DataOutputStream stream) throws IOException{
|
||||||
region("meta", stream, this::writeMeta);
|
write(stream, new StringMap());
|
||||||
region("content", stream, this::writeContentHeader);
|
|
||||||
region("map", stream, this::writeMap);
|
|
||||||
region("entities", stream, this::writeEntities);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void read(DataInputStream stream, CounterInputStream counter) throws IOException{
|
public final void read(DataInputStream stream, CounterInputStream counter) throws IOException{
|
||||||
@@ -44,7 +40,14 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
region("entities", stream, counter, this::readEntities);
|
region("entities", stream, counter, this::readEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeMeta(DataOutput stream) throws IOException{
|
public void write(DataOutputStream stream, StringMap extraTags) throws IOException{
|
||||||
|
region("meta", stream, out -> writeMeta(out, extraTags));
|
||||||
|
region("content", stream, this::writeContentHeader);
|
||||||
|
region("map", stream, this::writeMap);
|
||||||
|
region("entities", stream, this::writeEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
||||||
writeStringMap(stream, StringMap.of(
|
writeStringMap(stream, StringMap.of(
|
||||||
"saved", Time.millis(),
|
"saved", Time.millis(),
|
||||||
"playtime", headless ? 0 : control.saves.getTotalPlaytime(),
|
"playtime", headless ? 0 : control.saves.getTotalPlaytime(),
|
||||||
@@ -56,7 +59,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
"rules", Serialization.writeRulesJson(state.rules),
|
"rules", Serialization.writeRulesJson(state.rules),
|
||||||
"width", world.width(),
|
"width", world.width(),
|
||||||
"height", world.height()
|
"height", world.height()
|
||||||
));
|
).merge(tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readMeta(DataInput stream) throws IOException{
|
public void readMeta(DataInput stream) throws IOException{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package io.anuke.mindustry.maps;
|
package io.anuke.mindustry.maps;
|
||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.graphics.Texture;
|
import io.anuke.arc.graphics.Texture;
|
||||||
import io.anuke.arc.util.Log;
|
import io.anuke.arc.util.Log;
|
||||||
@@ -16,7 +15,7 @@ public class Map implements Comparable<Map>{
|
|||||||
/** Whether this is a custom map. */
|
/** Whether this is a custom map. */
|
||||||
public final boolean custom;
|
public final boolean custom;
|
||||||
/** Metadata. Author description, display name, etc. */
|
/** Metadata. Author description, display name, etc. */
|
||||||
public final ObjectMap<String, String> tags;
|
public final StringMap tags;
|
||||||
/** Base file of this map. File can be named anything at all. */
|
/** Base file of this map. File can be named anything at all. */
|
||||||
public final FileHandle file;
|
public final FileHandle file;
|
||||||
/** Format version. */
|
/** Format version. */
|
||||||
@@ -28,7 +27,7 @@ public class Map implements Comparable<Map>{
|
|||||||
/** Build that this map was created in. -1 = unknown or custom build. */
|
/** Build that this map was created in. -1 = unknown or custom build. */
|
||||||
public int build;
|
public int build;
|
||||||
|
|
||||||
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom, int version, int build){
|
public Map(FileHandle file, int width, int height, StringMap tags, boolean custom, int version, int build){
|
||||||
this.custom = custom;
|
this.custom = custom;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
@@ -38,15 +37,15 @@ public class Map implements Comparable<Map>{
|
|||||||
this.build = build;
|
this.build = build;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom, int version){
|
public Map(FileHandle file, int width, int height, StringMap tags, boolean custom, int version){
|
||||||
this(file, width, height, tags, custom, version, -1);
|
this(file, width, height, tags, custom, version, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom){
|
public Map(FileHandle file, int width, int height, StringMap tags, boolean custom){
|
||||||
this(file, width, height, tags, custom, -1);
|
this(file, width, height, tags, custom, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map(ObjectMap<String, String> tags){
|
public Map(StringMap tags){
|
||||||
this(Vars.customMapDirectory.child(tags.get("name", "unknown")), 0, 0, tags, true);
|
this(Vars.customMapDirectory.child(tags.get("name", "unknown")), 0, 0, tags, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package io.anuke.mindustry.maps;
|
package io.anuke.mindustry.maps;
|
||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.graphics.Texture;
|
import io.anuke.arc.graphics.Texture;
|
||||||
import io.anuke.arc.util.Disposable;
|
import io.anuke.arc.util.Disposable;
|
||||||
@@ -83,7 +82,7 @@ public class Maps implements Disposable{
|
|||||||
public void saveMap(ObjectMap<String, String> baseTags){
|
public void saveMap(ObjectMap<String, String> baseTags){
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ObjectMap<String, String> tags = new ObjectMap<>(baseTags);
|
StringMap tags = new StringMap(baseTags);
|
||||||
String name = tags.get("name");
|
String name = tags.get("name");
|
||||||
if(name == null) throw new IllegalArgumentException("Can't save a map with no name. How did this happen?");
|
if(name == null) throw new IllegalArgumentException("Can't save a map with no name. How did this happen?");
|
||||||
FileHandle file;
|
FileHandle file;
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import io.anuke.mindustry.world.blocks.*;
|
|||||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
||||||
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class MapGenerator extends Generator{
|
public class MapGenerator extends Generator{
|
||||||
@@ -69,119 +67,116 @@ public class MapGenerator extends Generator{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tile[][] tiles){
|
||||||
try{
|
for(int x = 0; x < width; x++){
|
||||||
for(int x = 0; x < width; x++){
|
for(int y = 0; y < height; y++){
|
||||||
for(int y = 0; y < height; y++){
|
tiles[x][y] = new Tile(x, y);
|
||||||
tiles[x][y] = new Tile(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapIO.readTiles(map, tiles);
|
|
||||||
Array<Point2> players = new Array<>();
|
|
||||||
Array<Point2> enemies = new Array<>();
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
if(tiles[x][y].block() instanceof CoreBlock){
|
|
||||||
players.add(new Point2(x, y));
|
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].overlay() == Blocks.spawn && enemySpawns != -1){
|
|
||||||
enemies.add(new Point2(x, y));
|
|
||||||
tiles[x][y].setOverlay(Blocks.air);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].block() instanceof BlockPart){
|
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Simplex simplex = new Simplex(Mathf.random(99999));
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
final double scl = 10;
|
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
int newX = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x, y) * distortion + x), 0, width - 1);
|
|
||||||
int newY = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x + 9999, y + 9999) * distortion + y), 0, height - 1);
|
|
||||||
|
|
||||||
if(((tile.block() instanceof StaticWall
|
|
||||||
&& tiles[newX][newY].block() instanceof StaticWall)
|
|
||||||
|| (tile.block() == Blocks.air && !tiles[newX][newY].block().synthetic())
|
|
||||||
|| (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall))){
|
|
||||||
tile.setBlock(tiles[newX][newY].block());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(distortFloor){
|
|
||||||
tile.setFloor(tiles[newX][newY].floor());
|
|
||||||
if(tiles[newX][newY].overlay() != Blocks.spawn && tile.overlay() != Blocks.spawn){
|
|
||||||
tile.setOverlay(tiles[newX][newY].overlay());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Decoration decor : decorations){
|
|
||||||
if(x > 0 && y > 0 && (tiles[x - 1][y].block() == decor.wall || tiles[x][y - 1].block() == decor.wall)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){
|
|
||||||
tile.setBlock(decor.wall);
|
|
||||||
}else if(tile.floor() == decor.floor && decor.wall instanceof Floor && Mathf.chance(decor.chance)){
|
|
||||||
tile.setFloor((Floor)decor.wall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
|
||||||
for(Item item : world.getZone().resources){
|
|
||||||
if(Mathf.chance(0.3)){
|
|
||||||
tile.entity.items.add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(enemySpawns != -1){
|
|
||||||
if(enemySpawns > enemies.size){
|
|
||||||
throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number for map: " + mapName);
|
|
||||||
}
|
|
||||||
|
|
||||||
enemies.shuffle();
|
|
||||||
for(int i = 0; i < enemySpawns; i++){
|
|
||||||
Point2 point = enemies.get(i);
|
|
||||||
tiles[point.x][point.y].setOverlay(Blocks.spawn);
|
|
||||||
|
|
||||||
int rad = 10, frad = 12;
|
|
||||||
|
|
||||||
for(int x = -rad; x <= rad; x++){
|
|
||||||
for(int y = -rad; y <= rad; y++){
|
|
||||||
int wx = x + point.x, wy = y + point.y;
|
|
||||||
double dst = Mathf.dst(x, y);
|
|
||||||
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
|
|
||||||
Tile tile = tiles[wx][wy];
|
|
||||||
if(tile.overlay() != Blocks.spawn){
|
|
||||||
tile.clearOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2 core = players.random();
|
|
||||||
if(core == null){
|
|
||||||
throw new IllegalArgumentException("All zone maps must have a core.");
|
|
||||||
}
|
|
||||||
|
|
||||||
loadout.setup(core.x, core.y);
|
|
||||||
|
|
||||||
world.prepareTiles(tiles);
|
|
||||||
world.setMap(map);
|
|
||||||
}catch(IOException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO this will probably not get the desired effect
|
||||||
|
MapIO.loadMap(map);
|
||||||
|
Array<Point2> players = new Array<>();
|
||||||
|
Array<Point2> enemies = new Array<>();
|
||||||
|
|
||||||
|
for(int x = 0; x < width; x++){
|
||||||
|
for(int y = 0; y < height; y++){
|
||||||
|
if(tiles[x][y].block() instanceof CoreBlock){
|
||||||
|
players.add(new Point2(x, y));
|
||||||
|
tiles[x][y].setBlock(Blocks.air);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tiles[x][y].overlay() == Blocks.spawn && enemySpawns != -1){
|
||||||
|
enemies.add(new Point2(x, y));
|
||||||
|
tiles[x][y].setOverlay(Blocks.air);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tiles[x][y].block() instanceof BlockPart){
|
||||||
|
tiles[x][y].setBlock(Blocks.air);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Simplex simplex = new Simplex(Mathf.random(99999));
|
||||||
|
|
||||||
|
for(int x = 0; x < width; x++){
|
||||||
|
for(int y = 0; y < height; y++){
|
||||||
|
final double scl = 10;
|
||||||
|
Tile tile = tiles[x][y];
|
||||||
|
int newX = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x, y) * distortion + x), 0, width - 1);
|
||||||
|
int newY = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x + 9999, y + 9999) * distortion + y), 0, height - 1);
|
||||||
|
|
||||||
|
if(((tile.block() instanceof StaticWall
|
||||||
|
&& tiles[newX][newY].block() instanceof StaticWall)
|
||||||
|
|| (tile.block() == Blocks.air && !tiles[newX][newY].block().synthetic())
|
||||||
|
|| (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall))){
|
||||||
|
tile.setBlock(tiles[newX][newY].block());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(distortFloor){
|
||||||
|
tile.setFloor(tiles[newX][newY].floor());
|
||||||
|
if(tiles[newX][newY].overlay() != Blocks.spawn && tile.overlay() != Blocks.spawn){
|
||||||
|
tile.setOverlay(tiles[newX][newY].overlay());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Decoration decor : decorations){
|
||||||
|
if(x > 0 && y > 0 && (tiles[x - 1][y].block() == decor.wall || tiles[x][y - 1].block() == decor.wall)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){
|
||||||
|
tile.setBlock(decor.wall);
|
||||||
|
}else if(tile.floor() == decor.floor && decor.wall instanceof Floor && Mathf.chance(decor.chance)){
|
||||||
|
tile.setFloor((Floor)decor.wall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
||||||
|
for(Item item : world.getZone().resources){
|
||||||
|
if(Mathf.chance(0.3)){
|
||||||
|
tile.entity.items.add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemySpawns != -1){
|
||||||
|
if(enemySpawns > enemies.size){
|
||||||
|
throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number for map: " + mapName);
|
||||||
|
}
|
||||||
|
|
||||||
|
enemies.shuffle();
|
||||||
|
for(int i = 0; i < enemySpawns; i++){
|
||||||
|
Point2 point = enemies.get(i);
|
||||||
|
tiles[point.x][point.y].setOverlay(Blocks.spawn);
|
||||||
|
|
||||||
|
int rad = 10, frad = 12;
|
||||||
|
|
||||||
|
for(int x = -rad; x <= rad; x++){
|
||||||
|
for(int y = -rad; y <= rad; y++){
|
||||||
|
int wx = x + point.x, wy = y + point.y;
|
||||||
|
double dst = Mathf.dst(x, y);
|
||||||
|
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
|
||||||
|
Tile tile = tiles[wx][wy];
|
||||||
|
if(tile.overlay() != Blocks.spawn){
|
||||||
|
tile.clearOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2 core = players.random();
|
||||||
|
if(core == null){
|
||||||
|
throw new IllegalArgumentException("All zone maps must have a core.");
|
||||||
|
}
|
||||||
|
|
||||||
|
loadout.setup(core.x, core.y);
|
||||||
|
|
||||||
|
world.prepareTiles(tiles);
|
||||||
|
world.setMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Decoration{
|
public static class Decoration{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.anuke.mindustry.maps.generators;
|
package io.anuke.mindustry.maps.generators;
|
||||||
|
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.StringMap;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.Blocks;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.Map;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
@@ -31,7 +31,7 @@ public abstract class RandomGenerator extends Generator{
|
|||||||
|
|
||||||
decorate(tiles);
|
decorate(tiles);
|
||||||
|
|
||||||
world.setMap(new Map(new ObjectMap<>()));
|
world.setMap(new Map(new StringMap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void decorate(Tile[][] tiles);
|
public abstract void decorate(Tile[][] tiles);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
|||||||
ui.deploy.hide();
|
ui.deploy.hide();
|
||||||
data.removeItems(zone.getLaunchCost());
|
data.removeItems(zone.getLaunchCost());
|
||||||
hide();
|
hide();
|
||||||
world.playZone(zone);
|
control.playZone(zone);
|
||||||
}
|
}
|
||||||
}).minWidth(150f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !canUnlock(zone) : !data.hasItems(zone.getLaunchCost())).uniformY().get();
|
}).minWidth(150f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !canUnlock(zone) : !data.hasItems(zone.getLaunchCost())).uniformY().get();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user