diff --git a/core/src/io/anuke/mindustry/editor/DrawOperation.java b/core/src/io/anuke/mindustry/editor/DrawOperation.java index df4e0374b9..1a638c74d0 100755 --- a/core/src/io/anuke/mindustry/editor/DrawOperation.java +++ b/core/src/io/anuke/mindustry/editor/DrawOperation.java @@ -9,6 +9,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.world; public class DrawOperation{ private LongArray array = new LongArray(); @@ -24,32 +25,46 @@ public class DrawOperation{ public void undo(MapEditor editor){ for(int i = array.size - 1; i >= 0; 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){ for(int i = 0; i < array.size; 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(() -> { if(type == OpType.floor.ordinal()){ tile.setFloor((Floor)content.block(to)); }else if(type == OpType.block.ordinal()){ Block block = content.block(to); - tile.setBlock(block); - if(block.isMultiblock()){ - editor.updateLinks(block, tile.x, tile.y); - } + world.setBlock(tile, block, tile.getTeam(), tile.rotation()); }else if(type == OpType.rotation.ordinal()){ tile.rotation(to); }else if(type == OpType.team.ordinal()){ tile.setTeam(Team.all[to]); - }else if(type == OpType.ore.ordinal()){ + }else if(type == OpType.overlay.ordinal()){ tile.setOverlayID(to); } }); @@ -60,8 +75,8 @@ public class DrawOperation{ class TileOpStruct{ short x; short y; - short value; byte type; + short value; } public enum OpType{ @@ -69,6 +84,6 @@ public class DrawOperation{ block, rotation, team, - ore + overlay } } diff --git a/core/src/io/anuke/mindustry/editor/EditorTile.java b/core/src/io/anuke/mindustry/editor/EditorTile.java index 23f1604c0d..63fa0a3a33 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTile.java +++ b/core/src/io/anuke/mindustry/editor/EditorTile.java @@ -33,54 +33,43 @@ public class EditorTile extends Tile{ return; } - Block previous = floor(); - Block ore = overlay(); - if(previous == type && ore == Blocks.air) return; + if(floor == type && overlayID() == 0) return; + if(overlayID() != 0) op(OpType.overlay, overlayID()); + if(floor != type) op(OpType.floor, floor.id); 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 public void setBlock(Block type){ - Block previous = block; - byte pteam = getTeamID(); - if(previous == type) return; + if(block == type) return; + op(OpType.block, block.id); 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 public void setTeam(Team team){ - byte previous = getTeamID(); - if(previous == team.ordinal()) return; + if(getTeamID() == team.ordinal()) return; + op(OpType.team, getTeamID()); super.setTeam(team); - op(TileOp.get(x, y, (byte)OpType.team.ordinal(), previous, (byte)team.ordinal())); } @Override - public void rotation(byte rotation){ - byte previous = rotation(); - if(previous == rotation) return; + public void rotation(int rotation){ + if(rotation == rotation()) return; + op(OpType.rotation, rotation()); super.rotation(rotation); - op(TileOp.get(x, y, (byte)OpType.rotation.ordinal(), previous, rotation)); } @Override - public void setOverlayID(byte ore){ - byte previous = overlayID(); - if(previous == ore) return; - super.setOverlayID(ore); - op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), previous, ore)); + public void setOverlayID(short overlay){ + if(overlayID() == overlay) return; + op(OpType.overlay, overlay); + super.setOverlayID(overlay); } @Override @@ -112,7 +101,7 @@ public class EditorTile extends Tile{ } } - private static void op(long op){ - ui.editor.editor.addTileOp(op); + private void op(OpType type, short value){ + ui.editor.editor.addTileOp(TileOp.get(x, y, (byte)type.ordinal(), value)); } } diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index b92d1ac3d0..41cab43717 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -15,21 +15,7 @@ public enum EditorTool{ public void touched(MapEditor editor, int x, int y){ if(!Structs.inBounds(x, y, editor.width(), editor.height())) return; - Tile tile = editor.tile(x, y); - - 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; - } + Tile tile = editor.tile(x, y).link(); 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; 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; } diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index 523f0fc2f3..f6f7f7c584 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.editor; -import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.StringMap; import io.anuke.arc.files.FileHandle; import io.anuke.arc.graphics.Pixmap; @@ -110,7 +109,7 @@ public class MapEditor{ } 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(){ diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 2d664bcfda..7a1c4add99 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -19,13 +19,11 @@ import io.anuke.arc.util.*; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.io.LegacyMapIO; import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; 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.storage.CoreBlock; @@ -122,7 +120,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ if(!editor.getTags().containsKey("name")){ editor.getTags().put("name", result.nameWithoutExtension()); } - MapIO.writeMap(result, editor.createMap(result), editor.tiles()); + MapIO.writeMap(result, editor.createMap(result)); }catch(Exception e){ ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, false))); Log.err(e); diff --git a/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java b/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java index 0e1f81affb..02d5453b22 100644 --- a/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapGenerateDialog.java @@ -322,7 +322,8 @@ public class MapGenerateDialog extends FloatingDialog{ } 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){ this.floor = floor.id; diff --git a/core/src/io/anuke/mindustry/io/LegacyMapIO.java b/core/src/io/anuke/mindustry/io/LegacyMapIO.java index 789e9d4c62..63381bbebb 100644 --- a/core/src/io/anuke/mindustry/io/LegacyMapIO.java +++ b/core/src/io/anuke/mindustry/io/LegacyMapIO.java @@ -1,6 +1,6 @@ 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.graphics.Color; import io.anuke.arc.graphics.Pixmap; @@ -27,7 +27,7 @@ public class LegacyMapIO{ public static Map readMap(FileHandle file, boolean custom) throws IOException{ try(DataInputStream stream = new DataInputStream(file.read(1024))){ - ObjectMap tags = new ObjectMap<>(); + StringMap tags = new StringMap(); //meta is uncompressed int version = stream.readInt(); @@ -107,7 +107,12 @@ public class LegacyMapIO{ Block block = content.block(stream.readByte()); 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){ byte tr = stream.readByte(); diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 7f07fbd989..760b7b6ae3 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -49,9 +49,10 @@ public class MapIO{ } public static void writeMap(FileHandle file, Map map) throws IOException{ - SaveIO.write(file); - try(DataOutputStream out = new DataOutputStream(file.write(false, bufferSize))){ - + try{ + SaveIO.write(file, map.tags); + }catch(Exception e){ + throw new IOException(e); } } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index d01c38c04c..7c4be59f79 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.io; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.IntMap; +import io.anuke.arc.collection.*; import io.anuke.arc.files.FileHandle; import io.anuke.arc.util.io.CounterInputStream; import io.anuke.arc.util.io.FastDeflaterOutputStream; @@ -100,18 +99,26 @@ public class SaveIO{ return file.sibling(file.name() + "-backup." + file.extension()); } - public static void write(FileHandle file){ - write(new FastDeflaterOutputStream(file.write(false, bufferSize))); + public static void write(FileHandle file, StringMap tags){ + 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; try{ stream = new DataOutputStream(os); stream.write(header); stream.writeInt(getVersion().version); - getVersion().write(stream); + if(tags == null){ + getVersion().write(stream); + }else{ + getVersion().write(stream, tags); + } stream.close(); }catch(Exception e){ throw new RuntimeException(e); diff --git a/core/src/io/anuke/mindustry/io/SaveVersion.java b/core/src/io/anuke/mindustry/io/SaveVersion.java index 5acf7e180f..f63f528520 100644 --- a/core/src/io/anuke/mindustry/io/SaveVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveVersion.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.io; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.StringMap; +import io.anuke.arc.collection.*; import io.anuke.arc.util.Time; import io.anuke.arc.util.io.CounterInputStream; import io.anuke.mindustry.entities.Entities; @@ -31,10 +30,7 @@ public abstract class SaveVersion extends SaveFileReader{ } public final void write(DataOutputStream stream) throws IOException{ - region("meta", stream, this::writeMeta); - region("content", stream, this::writeContentHeader); - region("map", stream, this::writeMap); - region("entities", stream, this::writeEntities); + write(stream, new StringMap()); } 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); } - 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( "saved", Time.millis(), "playtime", headless ? 0 : control.saves.getTotalPlaytime(), @@ -56,7 +59,7 @@ public abstract class SaveVersion extends SaveFileReader{ "rules", Serialization.writeRulesJson(state.rules), "width", world.width(), "height", world.height() - )); + ).merge(tags)); } public void readMeta(DataInput stream) throws IOException{ diff --git a/core/src/io/anuke/mindustry/maps/Map.java b/core/src/io/anuke/mindustry/maps/Map.java index 93f291e5aa..6765528ec0 100644 --- a/core/src/io/anuke/mindustry/maps/Map.java +++ b/core/src/io/anuke/mindustry/maps/Map.java @@ -1,8 +1,7 @@ package io.anuke.mindustry.maps; import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.ObjectMap; +import io.anuke.arc.collection.*; import io.anuke.arc.files.FileHandle; import io.anuke.arc.graphics.Texture; import io.anuke.arc.util.Log; @@ -16,7 +15,7 @@ public class Map implements Comparable{ /** Whether this is a custom map. */ public final boolean custom; /** Metadata. Author description, display name, etc. */ - public final ObjectMap tags; + public final StringMap tags; /** Base file of this map. File can be named anything at all. */ public final FileHandle file; /** Format version. */ @@ -28,7 +27,7 @@ public class Map implements Comparable{ /** Build that this map was created in. -1 = unknown or custom build. */ public int build; - public Map(FileHandle file, int width, int height, ObjectMap 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.tags = tags; this.file = file; @@ -38,15 +37,15 @@ public class Map implements Comparable{ this.build = build; } - public Map(FileHandle file, int width, int height, ObjectMap 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); } - public Map(FileHandle file, int width, int height, ObjectMap tags, boolean custom){ + public Map(FileHandle file, int width, int height, StringMap tags, boolean custom){ this(file, width, height, tags, custom, -1); } - public Map(ObjectMap tags){ + public Map(StringMap tags){ this(Vars.customMapDirectory.child(tags.get("name", "unknown")), 0, 0, tags, true); } diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index ec05d339c7..7f00fae5e0 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -1,8 +1,7 @@ package io.anuke.mindustry.maps; import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.ObjectMap; +import io.anuke.arc.collection.*; import io.anuke.arc.files.FileHandle; import io.anuke.arc.graphics.Texture; import io.anuke.arc.util.Disposable; @@ -83,7 +82,7 @@ public class Maps implements Disposable{ public void saveMap(ObjectMap baseTags){ try{ - ObjectMap tags = new ObjectMap<>(baseTags); + StringMap tags = new StringMap(baseTags); String name = tags.get("name"); if(name == null) throw new IllegalArgumentException("Can't save a map with no name. How did this happen?"); FileHandle file; diff --git a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java index 8f325fd8c4..aa318bf072 100644 --- a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java @@ -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.StorageBlock; -import java.io.IOException; - import static io.anuke.mindustry.Vars.world; public class MapGenerator extends Generator{ @@ -69,119 +67,116 @@ public class MapGenerator extends Generator{ @Override public void generate(Tile[][] tiles){ - try{ - for(int x = 0; x < width; x++){ - for(int y = 0; y < height; y++){ - tiles[x][y] = new Tile(x, y); - } + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ + tiles[x][y] = new Tile(x, y); } - - MapIO.readTiles(map, tiles); - Array players = new Array<>(); - Array 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 players = new Array<>(); + Array 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{ diff --git a/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java b/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java index 3704d192b6..23591e86df 100644 --- a/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java @@ -1,6 +1,6 @@ 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.maps.Map; import io.anuke.mindustry.world.Block; @@ -31,7 +31,7 @@ public abstract class RandomGenerator extends Generator{ decorate(tiles); - world.setMap(new Map(new ObjectMap<>())); + world.setMap(new Map(new StringMap())); } public abstract void decorate(Tile[][] tiles); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java index e36824afc1..99b03b803d 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java @@ -133,7 +133,7 @@ public class ZoneInfoDialog extends FloatingDialog{ ui.deploy.hide(); data.removeItems(zone.getLaunchCost()); 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();