Class package refactoring
This commit is contained in:
35
core/src/io/anuke/mindustry/maps/Map.java
Normal file
35
core/src/io/anuke/mindustry/maps/Map.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.ucore.function.Supplier;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class Map{
|
||||
/** Internal map name. This is the filename, without any extensions.*/
|
||||
public final String name;
|
||||
/** Whether this is a custom map.*/
|
||||
public final boolean custom;
|
||||
/** Metadata. Author description, display name, etc.*/
|
||||
public final MapMeta meta;
|
||||
/** Supplies a new input stream with the data of this map.*/
|
||||
public final Supplier<InputStream> stream;
|
||||
/** Preview texture.*/
|
||||
public Texture texture;
|
||||
|
||||
public Map(String name, MapMeta meta, boolean custom, Supplier<InputStream> streamSupplier){
|
||||
this.name = name;
|
||||
this.custom = custom;
|
||||
this.meta = meta;
|
||||
this.stream = streamSupplier;
|
||||
}
|
||||
|
||||
public Map(String unknownName, int width, int height){
|
||||
this(unknownName, new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null);
|
||||
}
|
||||
|
||||
public String getDisplayName(){
|
||||
return meta.tags.get("name", name);
|
||||
}
|
||||
}
|
||||
35
core/src/io/anuke/mindustry/maps/MapMeta.java
Normal file
35
core/src/io/anuke/mindustry/maps/MapMeta.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.IntIntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
|
||||
public class MapMeta{
|
||||
public final int version;
|
||||
public final ObjectMap<String, String> tags;
|
||||
public final int width, height;
|
||||
public final IntIntMap blockMap;
|
||||
|
||||
public MapMeta(int version, ObjectMap<String, String> tags, int width, int height, IntIntMap blockMap){
|
||||
this.version = version;
|
||||
this.tags = tags;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.blockMap = blockMap;
|
||||
}
|
||||
|
||||
public String author(){
|
||||
return tags.get("author", "unknown");
|
||||
}
|
||||
|
||||
public String description(){
|
||||
return tags.get("description", "unknown");
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return tags.get("name", "unknown");
|
||||
}
|
||||
|
||||
public boolean hasOreGen(){
|
||||
return !tags.get("oregen", "0").equals("0");
|
||||
}
|
||||
}
|
||||
139
core/src/io/anuke/mindustry/maps/MapTileData.java
Normal file
139
core/src/io/anuke/mindustry/maps/MapTileData.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.utils.IntIntMap;
|
||||
import io.anuke.ucore.util.Bits;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MapTileData{
|
||||
/**
|
||||
* Tile size: 4 bytes. <br>
|
||||
* 0: ground tile <br>
|
||||
* 1: wall tile <br>
|
||||
* 2: rotation + team <br>
|
||||
* 3: link (x/y) <br>
|
||||
* 4: elevation <br>
|
||||
*/
|
||||
private final static int TILE_SIZE = 5;
|
||||
|
||||
private final ByteBuffer buffer;
|
||||
private final int width, height;
|
||||
private final boolean readOnly;
|
||||
|
||||
private IntIntMap map;
|
||||
|
||||
public MapTileData(int width, int height){
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.map = null;
|
||||
this.readOnly = false;
|
||||
buffer = ByteBuffer.allocate(width * height * TILE_SIZE);
|
||||
}
|
||||
|
||||
public MapTileData(byte[] bytes, int width, int height, IntIntMap mapping, boolean readOnly){
|
||||
buffer = ByteBuffer.wrap(bytes);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.map = mapping;
|
||||
this.readOnly = readOnly;
|
||||
|
||||
if(mapping != null && !readOnly){
|
||||
for(int i = 0; i < width * height; i++){
|
||||
TileDataMarker marker = new TileDataMarker();
|
||||
read(marker);
|
||||
buffer.position(i * TILE_SIZE);
|
||||
write(marker);
|
||||
}
|
||||
buffer.position(0);
|
||||
this.map = null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toArray(){
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
public int width(){
|
||||
return width;
|
||||
}
|
||||
|
||||
public int height(){
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte to a specific position.
|
||||
*/
|
||||
public void write(int x, int y, DataPosition position, byte data){
|
||||
buffer.put((x + width * y) * TILE_SIZE + position.ordinal(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte at a specific position.
|
||||
*/
|
||||
public byte read(int x, int y, DataPosition position){
|
||||
return buffer.get((x + width * y) * TILE_SIZE + position.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns the next tile data.
|
||||
*/
|
||||
public TileDataMarker read(TileDataMarker marker){
|
||||
marker.read(buffer);
|
||||
return marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this tile data marker.
|
||||
*/
|
||||
public void write(TileDataMarker marker){
|
||||
marker.write(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets read position to the specified coordinates
|
||||
*/
|
||||
public void position(int x, int y){
|
||||
buffer.position((x + width * y) * TILE_SIZE);
|
||||
}
|
||||
|
||||
public TileDataMarker newDataMarker(){
|
||||
return new TileDataMarker();
|
||||
}
|
||||
|
||||
public enum DataPosition{
|
||||
floor, wall, link, rotationTeam, elevation
|
||||
}
|
||||
|
||||
public class TileDataMarker{
|
||||
public byte floor, wall;
|
||||
public byte link;
|
||||
public byte rotation;
|
||||
public byte team;
|
||||
public byte elevation;
|
||||
|
||||
public void read(ByteBuffer buffer){
|
||||
floor = buffer.get();
|
||||
wall = buffer.get();
|
||||
link = buffer.get();
|
||||
byte rt = buffer.get();
|
||||
elevation = buffer.get();
|
||||
rotation = Bits.getLeftByte(rt);
|
||||
team = Bits.getRightByte(rt);
|
||||
|
||||
if(map != null){
|
||||
floor = (byte) map.get(floor, floor);
|
||||
wall = (byte) map.get(wall, wall);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(ByteBuffer buffer){
|
||||
if(readOnly) throw new IllegalArgumentException("This data is read-only.");
|
||||
buffer.put(floor);
|
||||
buffer.put(wall);
|
||||
buffer.put(link);
|
||||
buffer.put(Bits.packByte(rotation, team));
|
||||
buffer.put(elevation);
|
||||
}
|
||||
}
|
||||
}
|
||||
196
core/src/io/anuke/mindustry/maps/Maps.java
Normal file
196
core/src/io/anuke/mindustry/maps/Maps.java
Normal file
@@ -0,0 +1,196 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Base64Coder;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.io.MapIO;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.function.Supplier;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.ThreadArray;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Maps implements Disposable{
|
||||
/**List of all built-in maps.*/
|
||||
private static final String[] defaultMapNames = {};
|
||||
/**Tile format version.*/
|
||||
private static final int version = 0;
|
||||
|
||||
/**Maps map names to the real maps.*/
|
||||
private ObjectMap<String, Map> maps = new ObjectMap<>();
|
||||
/**All maps stored in an ordered array.*/
|
||||
private Array<Map> allMaps = new ThreadArray<>();
|
||||
/**Temporary array used for returning things.*/
|
||||
private Array<Map> returnArray = new ThreadArray<>();
|
||||
/**Used for storing a list of custom map names for GWT.*/
|
||||
private Array<String> customMapNames;
|
||||
|
||||
public Maps(){
|
||||
|
||||
}
|
||||
|
||||
/**Returns a list of all maps, including custom ones.*/
|
||||
public Array<Map> all(){
|
||||
return allMaps;
|
||||
}
|
||||
|
||||
/**Returns a list of only custom maps.*/
|
||||
public Array<Map> customMaps(){
|
||||
returnArray.clear();
|
||||
for(Map map : allMaps){
|
||||
if(map.custom) returnArray.add(map);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**Returns a list of only default maps.*/
|
||||
public Array<Map> defaultMaps(){
|
||||
returnArray.clear();
|
||||
for(Map map : allMaps){
|
||||
if(!map.custom) returnArray.add(map);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**Returns map by internal name.*/
|
||||
public Map getByName(String name){
|
||||
return maps.get(name);
|
||||
}
|
||||
|
||||
/**Load all maps. Should be called at application start.*/
|
||||
public void load(){
|
||||
try {
|
||||
for (String name : defaultMapNames) {
|
||||
FileHandle file = Gdx.files.internal("maps/" + name + "." + mapExtension);
|
||||
loadMap(file.nameWithoutExtension(), file::read, false);
|
||||
}
|
||||
}catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
loadCustomMaps();
|
||||
}
|
||||
|
||||
/**Save a map. This updates all values and stored data necessary.*/
|
||||
public void saveMap(String name, MapTileData data, ObjectMap<String, String> tags){
|
||||
try {
|
||||
if (!gwt) {
|
||||
FileHandle file = customMapDirectory.child(name + "." + mapExtension);
|
||||
MapIO.writeMap(file.write(false), tags, data);
|
||||
} else {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
MapIO.writeMap(stream, tags, data);
|
||||
Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray())));
|
||||
if(!customMapNames.contains(name, false)){
|
||||
customMapNames.add(name);
|
||||
Settings.putJson("custom-maps", customMapNames);
|
||||
}
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
if(maps.containsKey(name)){
|
||||
if(maps.get(name).texture != null) {
|
||||
maps.get(name).texture.dispose();
|
||||
maps.get(name).texture = null;
|
||||
}
|
||||
allMaps.removeValue(maps.get(name), true);
|
||||
}
|
||||
|
||||
Map map = new Map(name, new MapMeta(version, tags, data.width(), data.height(), null), true, getStreamFor(name));
|
||||
if (!headless){
|
||||
map.texture = new Texture(MapIO.generatePixmap(data));
|
||||
}
|
||||
allMaps.add(map);
|
||||
|
||||
maps.put(name, map);
|
||||
}catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**Removes a map completely.*/
|
||||
public void removeMap(Map map){
|
||||
if(map.texture != null){
|
||||
map.texture.dispose();
|
||||
map.texture = null;
|
||||
}
|
||||
|
||||
maps.remove(map.name);
|
||||
allMaps.removeValue(map, true);
|
||||
|
||||
if (!gwt) {
|
||||
customMapDirectory.child(map.name + "." + mapExtension).delete();
|
||||
} else {
|
||||
customMapNames.removeValue(map.name, false);
|
||||
Settings.putString("map-data-" + map.name, "");
|
||||
Settings.putJson("custom-maps", customMapNames);
|
||||
Settings.save();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMap(String name, Supplier<InputStream> supplier, boolean custom) throws IOException{
|
||||
try(DataInputStream ds = new DataInputStream(supplier.get())) {
|
||||
MapMeta meta = MapIO.readMapMeta(ds);
|
||||
Map map = new Map(name, meta, custom, supplier);
|
||||
|
||||
if (!headless){
|
||||
map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true)));
|
||||
}
|
||||
|
||||
maps.put(map.name, map);
|
||||
allMaps.add(map);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCustomMaps(){
|
||||
if(!gwt){
|
||||
for(FileHandle file : customMapDirectory.list()){
|
||||
try{
|
||||
if(file.extension().equalsIgnoreCase(mapExtension)){
|
||||
loadMap(file.nameWithoutExtension(), file::read, true);
|
||||
}
|
||||
}catch (Exception e){
|
||||
Log.err("Failed to load custom map file '{0}'!", file);
|
||||
Log.err(e);
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
customMapNames = Settings.getJson("custom-maps", Array.class);
|
||||
|
||||
for(String name : customMapNames){
|
||||
try{
|
||||
String data = Settings.getString("map-data-" + name, "");
|
||||
byte[] bytes = Base64Coder.decode(data);
|
||||
loadMap(name, () -> new ByteArrayInputStream(bytes), true);
|
||||
}catch (Exception e){
|
||||
Log.err("Failed to load custom map '{0}'!", name);
|
||||
Log.err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Returns an input stream supplier for a given map name.*/
|
||||
private Supplier<InputStream> getStreamFor(String name){
|
||||
if(!gwt){
|
||||
return customMapDirectory.child(name + "." + mapExtension)::read;
|
||||
}else{
|
||||
String data = Settings.getString("map-data-" + name, "");
|
||||
byte[] bytes = Base64Coder.decode(data);
|
||||
return () -> new ByteArrayInputStream(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
4
core/src/io/anuke/mindustry/maps/Sector.java
Normal file
4
core/src/io/anuke/mindustry/maps/Sector.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
public class Sector{
|
||||
}
|
||||
19
core/src/io/anuke/mindustry/maps/Sectors.java
Normal file
19
core/src/io/anuke/mindustry/maps/Sectors.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.ucore.util.GridMap;
|
||||
|
||||
public class Sectors{
|
||||
private GridMap<Sector> grid = new GridMap<>();
|
||||
|
||||
public Sectors(){
|
||||
|
||||
}
|
||||
|
||||
public void load(){
|
||||
|
||||
}
|
||||
|
||||
public void save(){
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user