From 172ac78466dea4ae437916da979af60ad6c25c5f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 17 Mar 2018 21:21:24 -0400 Subject: [PATCH] New map format, completely broke loading or playing --- build.gradle | 2 +- .../sprites/blocks/turrets/plasmaturret.png | Bin 369 -> 0 bytes .../sprites/blocks/turrets/turret.png | Bin 317 -> 0 bytes core/assets/version.properties | 4 +- core/src/io/anuke/mindustry/Vars.java | 3 + core/src/io/anuke/mindustry/ai/Pathfind.java | 41 +- core/src/io/anuke/mindustry/core/Control.java | 38 +- .../io/anuke/mindustry/core/GameState.java | 1 - core/src/io/anuke/mindustry/core/Logic.java | 14 +- .../io/anuke/mindustry/core/NetClient.java | 19 +- .../io/anuke/mindustry/core/NetServer.java | 22 +- .../src/io/anuke/mindustry/core/Renderer.java | 28 +- core/src/io/anuke/mindustry/core/UI.java | 5 +- core/src/io/anuke/mindustry/core/World.java | 105 ++--- .../io/anuke/mindustry/entities/Bullet.java | 26 +- .../anuke/mindustry/entities/BulletType.java | 16 +- .../src/io/anuke/mindustry/game/Tutorial.java | 20 +- .../mindustry/graphics/BlockRenderer.java | 20 - .../anuke/mindustry/input/InputHandler.java | 9 +- core/src/io/anuke/mindustry/io/Map.java | 20 + core/src/io/anuke/mindustry/io/MapIO.java | 2 + core/src/io/anuke/mindustry/io/MapMeta.java | 32 ++ .../io/anuke/mindustry/io/MapTileData.java | 75 +++ core/src/io/anuke/mindustry/io/Maps.java | 263 +++-------- .../anuke/mindustry/io/SaveFileVersion.java | 5 +- core/src/io/anuke/mindustry/io/SaveIO.java | 4 +- core/src/io/anuke/mindustry/io/SaveMeta.java | 5 +- core/src/io/anuke/mindustry/io/Saves.java | 1 - .../anuke/mindustry/io/versions/Save16.java | 166 ++----- .../mindustry/mapeditor/DrawOperation.java | 40 -- .../anuke/mindustry/mapeditor/EditorTool.java | 87 ---- .../anuke/mindustry/mapeditor/MapEditor.java | 201 -------- .../mindustry/mapeditor/MapEditorDialog.java | 439 ------------------ .../anuke/mindustry/mapeditor/MapFilter.java | 244 ---------- .../mapeditor/MapGenerateDialog.java | 105 ----- .../mindustry/mapeditor/MapLoadDialog.java | 73 --- .../mindustry/mapeditor/MapResizeDialog.java | 67 --- .../mindustry/mapeditor/MapSaveDialog.java | 74 --- .../io/anuke/mindustry/mapeditor/MapView.java | 328 ------------- .../mindustry/mapeditor/OperationStack.java | 55 --- .../src/io/anuke/mindustry/net/NetworkIO.java | 259 ++--------- core/src/io/anuke/mindustry/net/Packets.java | 25 +- .../io/anuke/mindustry/resource/Weapon.java | 4 +- .../mindustry/ui/dialogs/LevelDialog.java | 47 +- .../mindustry/ui/dialogs/LoadDialog.java | 2 +- .../mindustry/ui/dialogs/PausedDialog.java | 3 +- .../mindustry/ui/fragments/DebugFragment.java | 2 - .../mindustry/ui/fragments/MenuFragment.java | 4 +- .../io/anuke/mindustry/world/ColorMapper.java | 4 - core/src/io/anuke/mindustry/world/Map.java | 10 - .../io/anuke/mindustry/world/Placement.java | 11 +- core/src/io/anuke/mindustry/world/Tile.java | 31 +- .../anuke/mindustry/world/WorldGenerator.java | 77 +-- .../world/blocks/types/defense/Turret.java | 2 +- .../world/blocks/types/storage/CoreBlock.java | 7 + 55 files changed, 483 insertions(+), 2664 deletions(-) delete mode 100644 core/assets-raw/sprites/blocks/turrets/plasmaturret.png delete mode 100644 core/assets-raw/sprites/blocks/turrets/turret.png create mode 100644 core/src/io/anuke/mindustry/io/Map.java create mode 100644 core/src/io/anuke/mindustry/io/MapMeta.java create mode 100644 core/src/io/anuke/mindustry/io/MapTileData.java delete mode 100755 core/src/io/anuke/mindustry/mapeditor/DrawOperation.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/EditorTool.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapEditor.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapFilter.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapLoadDialog.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java delete mode 100644 core/src/io/anuke/mindustry/mapeditor/MapView.java delete mode 100755 core/src/io/anuke/mindustry/mapeditor/OperationStack.java delete mode 100644 core/src/io/anuke/mindustry/world/Map.java diff --git a/build.gradle b/build.gradle index 84899de744..0e44959044 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ allprojects { appName = 'Mindustry' gdxVersion = '1.9.8' aiVersion = '1.8.1' - uCoreVersion = '872bce6' + uCoreVersion = '9503bcb' getVersionString = { String buildVersion = getBuildVersion() diff --git a/core/assets-raw/sprites/blocks/turrets/plasmaturret.png b/core/assets-raw/sprites/blocks/turrets/plasmaturret.png deleted file mode 100644 index e6e7a1d32866fffba590867261b70890e0d89524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 369 zcmeAS@N?(olHy`uVBq!ia0y~yU;weXIM^5%7`Ki;O^-g5Z=fq&cMKM)6>Nh0q{U$<>~ z%5y-^>qoTJ=BGVBe&5^f+-2By`}~o|R*VAAId^Luv~-W{(aCD@f%d2WyN^5mLTc}xZ$dFvl?%Ou)NKBRc1 RjDdlH!PC{xWt~$(695d`Z>0bL diff --git a/core/assets/version.properties b/core/assets/version.properties index bf295f77bb..278f49ba23 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sat Mar 17 11:51:42 EDT 2018 +#Sat Mar 17 21:20:30 EDT 2018 version=release -androidBuildCode=535 +androidBuildCode=538 name=Mindustry code=3.4 build=custom build diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 2aa22bbcbe..8ce518a629 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -53,6 +53,9 @@ public class Vars{ //save file directory public static final FileHandle saveDirectory = gwt ? null : UCore.isAssets() ? Gdx.files.local("../../desktop/mindustry-saves") : Gdx.files.local("mindustry-saves/"); + + public static final String mapExtension = "mmap"; + public static final String saveExtension = "msav"; //scale of the font public static float fontscale = Math.max(Unit.dp.scl(1f)/2f, 0.5f); //camera zoom displayed on startup diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 5df4030167..bf1a19b95f 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -1,17 +1,11 @@ package io.anuke.mindustry.ai; -import com.badlogic.gdx.ai.pfa.PathFinderRequest; import com.badlogic.gdx.ai.pfa.PathSmoother; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.Tile; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Log; - -import static io.anuke.mindustry.Vars.state; -import static io.anuke.mindustry.Vars.world; public class Pathfind{ /**Maximum time taken per frame on pathfinding for a single path.*/ @@ -40,6 +34,7 @@ public class Pathfind{ /**Update the pathfinders and continue calculating the path if it hasn't been calculated yet. * This method is run each frame.*/ public void update(){ + /* //go through each spawnpoint, and if it's not found a path yet, update it for(int i = 0; i < world.getSpawns().size; i ++){ @@ -60,46 +55,20 @@ public class Pathfind{ point.request.pathFound = true; } } - } + }*/ } - //1300-1500ms, usually 1400 unoptimized on Caldera - /**Benchmark pathfinding speed. Debugging stuff.*/ - public void benchmark(){ - SpawnPoint point = world.getSpawns().first(); - int amount = 100; - - //warmup - for(int i = 0; i < 100; i ++){ - point.finder.searchNodePath(point.start, world.getCore(), state.difficulty.heuristic, point.path); - point.path.clear(); - } - - Timers.mark(); - for(int i = 0; i < amount; i ++){ - point.finder.searchNodePath(point.start, world.getCore(), state.difficulty.heuristic, point.path); - point.path.clear(); - } - Log.info("Time elapsed: {0}ms\nAverage MS per path: {1}", Timers.elapsed(), Timers.elapsed()/amount); - } - - /**Reset and clear the paths.*/ - public void resetPaths(){ - for(int i = 0; i < world.getSpawns().size; i ++){ - resetPathFor(world.getSpawns().get(i)); - } - } - private void resetPathFor(SpawnPoint point){ + /* point.finder = new OptimizedPathFinder<>(graph); point.path.clear(); point.pathTiles = null; - + //TODO point.request = new PathFinderRequest<>(point.start, world.getCore(), state.difficulty.heuristic, point.path); - point.request.statusChanged = true; //IMPORTANT! + point.request.statusChanged = true; //IMPORTANT!*/ } /**Finds the closest tile to a position, in an array of tiles.*/ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index c46e5733ae..6a9cb3b196 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -9,25 +9,26 @@ import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Tutorial; import io.anuke.mindustry.game.UpgradeInventory; -import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.DefaultKeybinds; import io.anuke.mindustry.input.DesktopInput; import io.anuke.mindustry.input.InputHandler; +import io.anuke.mindustry.io.Map; import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.io.Saves; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Mech; import io.anuke.mindustry.resource.Weapon; -import io.anuke.mindustry.world.Map; import io.anuke.ucore.UCore; import io.anuke.ucore.core.*; import io.anuke.ucore.core.Inputs.DeviceType; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.modules.Module; import io.anuke.ucore.scene.ui.layout.Unit; -import io.anuke.ucore.util.*; +import io.anuke.ucore.util.Atlas; +import io.anuke.ucore.util.InputProxy; +import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; @@ -126,10 +127,6 @@ public class Control extends Module{ KeyBinds.load(); - for(Map map : world.maps().list()){ - Settings.defaults("hiscore" + map.name, 0); - } - player = new Player(); player.name = Settings.getString("name"); player.mech = android ? Mech.standardShip : Mech.standard; @@ -188,11 +185,15 @@ public class Control extends Module{ Events.on(GameOverEvent.class, () -> { Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); - Sounds.play("corexplode"); + + + //TODO effects??? + //Sounds.play("corexplode"); + /* for(int i = 0; i < 16; i ++){ Timers.run(i*2, ()-> Effects.effect(Fx.explosion, world.getCore().worldx()+Mathf.range(40), world.getCore().worldy()+Mathf.range(40))); } - Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy()); + Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy());*/ ui.restart.show(); @@ -249,23 +250,6 @@ public class Control extends Module{ return tutorial; } - private void checkOldUser(){ - boolean hasPlayed = false; - - for(Map map : world.maps().getAllMaps()){ - if(Settings.getInt("hiscore" + map.name) != 0){ - hasPlayed = true; - break; - } - } - - if(hasPlayed && Settings.getString("lastVersion").equals("3.2")){ - Timers.runTask(1f, () -> ui.showInfo("$text.changes")); - Settings.putString("lastVersion", "3.3"); - Settings.save(); - } - } - @Override public void dispose(){ Platform.instance.onGameExit(); @@ -292,8 +276,6 @@ public class Control extends Module{ Entities.initPhysics(); Platform.instance.updateRPC(); - - checkOldUser(); } @Override diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index 23bb65f0c2..afd45fde8c 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -14,7 +14,6 @@ public class GameState{ public final Inventory inventory = new Inventory(); public int wave = 1; - public int lastUpdated = -1; public float wavetime; public float extrawavetime; public int enemies = 0; diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 3d9c0c603a..7ed4c5dfa8 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -11,7 +11,6 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.WaveCreator; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; -import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; @@ -51,7 +50,6 @@ public class Logic extends Module { state.extrawavetime = maxwavespace * state.difficulty.maxTimeScaling; state.wavetime = wavespace * state.difficulty.timeScaling; state.enemies = 0; - state.lastUpdated = -1; state.gameOver = false; state.inventory.clearItems(); state.allyTeams.clear(); @@ -67,11 +65,6 @@ public class Logic extends Module { public void runWave(){ - if(state.lastUpdated < state.wave + 1){ - world.pathfinder().resetPaths(); - state.lastUpdated = state.wave + 1; - } - //TODO spawn enemies state.wave ++; @@ -93,7 +86,7 @@ public class Logic extends Module { if(!Net.client()) world.pathfinder().update(); - if(world.getCore() != null && world.getCore().block() != ProductionBlocks.core && !state.gameOver){ + if(world.getAllyCores().size == 0 && !state.gameOver){ state.gameOver = true; if(Net.server()) NetEvents.handleGameOver(); Events.fire(GameOverEvent.class); @@ -105,11 +98,6 @@ public class Logic extends Module { if(state.enemies <= 0){ if(!world.getMap().name.equals("tutorial")) state.wavetime -= delta(); - - if(state.lastUpdated < state.wave + 1 && state.wavetime < aheadPathfinding){ //start updating beforehand - world.pathfinder().resetPaths(); - state.lastUpdated = state.wave + 1; - } }else{ state.extrawavetime -= delta(); } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 15b3ee9c5d..59943bf2c8 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -14,10 +14,8 @@ import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.NetworkIO; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Placement; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.BaseBulletType; import io.anuke.ucore.entities.Entities; @@ -101,18 +99,6 @@ public class NetClient extends Module { finishConnecting(); }); - Net.handleClient(CustomMapPacket.class, packet -> { - Log.info("Recieved custom map: {0} bytes.", packet.stream.available()); - - //custom map is always sent before world data - Map map = NetworkIO.loadMap(packet.stream); - - world.maps().setNetworkMap(map); - - MapAckPacket ack = new MapAckPacket(); - Net.send(ack, SendMode.tcp); - }); - Net.handleClient(SyncPacket.class, packet -> { if (connecting) return; int players = 0; @@ -253,10 +239,7 @@ public class NetClient extends Module { }); Net.handleClient(GameOverPacket.class, packet -> { - if(world.getCore().block() != ProductionBlocks.core && - world.getCore().entity != null){ - world.getCore().entity.onDeath(true); - } + //TODO core death effects quiet = true; ui.restart.show(); }); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 364a3a522e..6e9ea73031 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -97,25 +97,7 @@ public class NetServer extends Module{ admins.getTrace(ip).playerid = player.id; - if(world.getMap().custom){ - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - NetworkIO.writeMap(world.getMap(), stream); - CustomMapPacket data = new CustomMapPacket(); - data.stream = new ByteArrayInputStream(stream.toByteArray()); - Net.sendStream(id, data); - - Log.info("Sending custom map: Packed {0} uncompressed bytes of MAP data.", stream.size()); - }else{ - //hack-- simulate the map ack packet recieved to send the world data to the client. - Net.handleServerReceived(id, new MapAckPacket()); - } - - Platform.instance.updateRPC(); - }); - - Net.handleServer(MapAckPacket.class, (id, packet) -> { - Player player = connections.get(id); - + //TODO try DeflaterOutputStream ByteArrayOutputStream stream = new ByteArrayOutputStream(); NetworkIO.writeWorld(player, weapons.get(player.name, new ByteArray()), stream); WorldData data = new WorldData(); @@ -123,6 +105,8 @@ public class NetServer extends Module{ Net.sendStream(id, data); Log.info("Packed {0} uncompressed bytes of WORLD data.", stream.size()); + + Platform.instance.updateRPC(); }); Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> { diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index a0388fedae..681fa17f6f 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -16,7 +16,6 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.SyncEntity; import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.BlockRenderer; import io.anuke.mindustry.graphics.Shaders; @@ -26,7 +25,6 @@ import io.anuke.mindustry.ui.fragments.ToolFragment; import io.anuke.mindustry.world.BlockBar; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.ucore.core.*; import io.anuke.ucore.entities.EffectEntity; import io.anuke.ucore.entities.Entities; @@ -119,14 +117,11 @@ public class Renderer extends RendererModule{ }else{ boolean smoothcam = Settings.getBool("smoothcam"); - if(world.getCore() == null || world.getCore().block() == ProductionBlocks.core){ - if(!smoothcam){ - setCamera(player.x, player.y); - }else{ - smoothCamera(player.x, player.y, android ? 0.3f : 0.14f); - } + + if(!smoothcam){ + setCamera(player.x, player.y); }else{ - smoothCamera(world.getCore().worldx(), world.getCore().worldy(), 0.4f); + smoothCamera(player.x, player.y, android ? 0.3f : 0.14f); } if(Settings.getBool("pixelate")) @@ -392,6 +387,8 @@ public class Renderer extends RendererModule{ //draw tutorial placement point if(world.getMap().name.equals("tutorial") && control.tutorial().showBlock()){ + //TODO draw placement point for tutorial + /* int x = world.getCore().x + control.tutorial().getPlacePoint().x; int y = world.getCore().y + control.tutorial().getPlacePoint().y; int rot = control.tutorial().getPlaceRotation(); @@ -405,7 +402,7 @@ public class Renderer extends RendererModule{ if(rot != -1){ Lines.lineAngle(x * tilesize, y * tilesize, rot * 90, 6); } - Draw.reset(); + Draw.reset();*/ } //draw config selected block @@ -435,17 +432,6 @@ public class Renderer extends RendererModule{ input.placeMode.draw(control.input().getBlockX(), control.input().getBlockY(), control.input().getBlockEndX(), control.input().getBlockEndY()); - - Lines.stroke(1f); - Draw.color(Color.SCARLET); - for(SpawnPoint spawn : world.getSpawns()){ - Lines.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace); - } - - if(world.getCore() != null) { - Draw.color(Color.LIME); - Lines.poly(world.getSpawnX(), world.getSpawnY(), 4, 6f, Timers.time() * 2f); - } if(input.breakMode == PlaceMode.holdDelete) input.breakMode.draw(tilex, tiley, 0, 0); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 75205309c0..a54252e78f 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -8,7 +8,6 @@ import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.utils.Align; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.Platform; -import io.anuke.mindustry.mapeditor.MapEditorDialog; import io.anuke.mindustry.ui.dialogs.*; import io.anuke.mindustry.ui.fragments.*; import io.anuke.ucore.core.Core; @@ -44,7 +43,7 @@ public class UI extends SceneModule{ public PausedDialog paused; public SettingsMenuDialog settings; public ControlsDialog controls; - public MapEditorDialog editor; + public FloatingDialog editor; //TODO change back to map editor dialog public LanguageDialog language; public BansDialog bans; public AdminsDialog admins; @@ -144,7 +143,7 @@ public class UI extends SceneModule{ @Override public void init(){ - editor = new MapEditorDialog(); + (editor = new FloatingDialog("The editor is currently broken.")).addCloseButton(); controls = new ControlsDialog(); restart = new RestartDialog(); join = new JoinDialog(); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index d06c4d6a3d..5b29747d19 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -6,20 +6,19 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.ai.Pathfind; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.game.SpawnPoint; +import io.anuke.mindustry.io.Map; import io.anuke.mindustry.io.Maps; -import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.WorldGenerator; import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.DistributionBlocks; import io.anuke.mindustry.world.blocks.ProductionBlocks; -import io.anuke.mindustry.world.blocks.WeaponBlocks; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.modules.Module; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Tmp; -import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.tilesize; public class World extends Module{ @@ -31,42 +30,41 @@ public class World extends Module{ private Maps maps = new Maps(); private Array allyCores = new Array<>(); private Array enemyCores = new Array<>(); - private Array spawns = new Array<>(); private Array tempTiles = new Array<>(); public World(){ - maps.loadMaps(); - currentMap = maps.getMap(0); + maps.load(); } @Override public void dispose(){ maps.dispose(); } - - public Array getSpawns(){ - return spawns; - } - - public Tile getCore(){ - return core; - } public Maps maps(){ return maps; } - + public Pathfind pathfinder(){ return pathfind; } + public Array getAllyCores() { + return allyCores; + } + + public Array getEnemyCores() { + return enemyCores; + } + + //TODO proper spawnpoints! public float getSpawnX(){ - return core.worldx(); + return width() * tilesize/2f; } public float getSpawnY(){ - return core.worldy() - tilesize*2; + return height() * tilesize/2f; } public boolean solid(int x, int y){ @@ -105,11 +103,11 @@ public class World extends Module{ } public int width(){ - return currentMap.getWidth(); + return currentMap.meta.width; } public int height(){ - return currentMap.getHeight(); + return currentMap.meta.height; } public Tile tile(int packed){ @@ -136,16 +134,6 @@ public class World extends Module{ return tiles; } - private void createTiles(){ - for(int x = 0; x < tiles.length; x ++){ - for(int y = 0; y < tiles[0].length; y ++){ - if(tiles[x][y] == null){ - tiles[x][y] = new Tile(x, y, Blocks.stone); - } - } - } - } - private void clearTileEntities(){ for(int x = 0; x < tiles.length; x ++){ for(int y = 0; y < tiles[0].length; y ++){ @@ -155,43 +143,40 @@ public class World extends Module{ } } } + + /**Resizes the tile array to the specified size and returns the resulting tile array. + * Only use for loading saves!*/ + public Tile[][] createTiles(int width, int height){ + if(tiles != null){ + clearTileEntities(); + + if(tiles.length != width || tiles[0].length != height){ + tiles = new Tile[width][height]; + } + }else{ + tiles = new Tile[width][height]; + } + + return tiles; + } public void loadMap(Map map){ - loadMap(map, MathUtils.random(0, 99999)); + loadMap(map, MathUtils.random(0, 999999)); } public void loadMap(Map map, int seed){ - currentMap = map; - - if(tiles != null){ - clearTileEntities(); - - if(tiles.length != map.getWidth() || tiles[0].length != map.getHeight()){ - tiles = new Tile[map.getWidth()][map.getHeight()]; - } - - createTiles(); - }else{ - tiles = new Tile[map.getWidth()][map.getHeight()]; - - createTiles(); - } - - spawns.clear(); - - Entities.resizeTree(0, 0, map.getWidth() * tilesize, map.getHeight() * tilesize); - + this.currentMap = map; this.seed = seed; - - core = WorldGenerator.generate(map.pixmap, tiles, spawns); - Placement.placeBlock(core.x, core.y, ProductionBlocks.core, 0, false, false); - - control.tutorial().setDefaultBlocks(core.x, core.y); + int width = map.meta.width, height = map.meta.height; - pathfind.resetPaths(); + createTiles(width, height); + + Entities.resizeTree(0, 0, width * tilesize, height * tilesize); + + WorldGenerator.generate(tiles, maps.readTileData(map)); } - + void set(int x, int y, Block type, int rot){ if(!Mathf.inBounds(x, y, tiles)){ return; @@ -201,7 +186,7 @@ public class World extends Module{ } tiles[x][y].setBlock(type, rot); } - + public int getSeed(){ return seed; } diff --git a/core/src/io/anuke/mindustry/entities/Bullet.java b/core/src/io/anuke/mindustry/entities/Bullet.java index 6f1cd4c076..b3174a0544 100644 --- a/core/src/io/anuke/mindustry/entities/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/Bullet.java @@ -3,17 +3,31 @@ package io.anuke.mindustry.entities; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.entities.BulletEntity; +import io.anuke.ucore.entities.Entity; import io.anuke.ucore.util.Timer; import static io.anuke.mindustry.Vars.*; public class Bullet extends BulletEntity{ public Timer timer = new Timer(3); + public Team team; public Bullet(BulletType type, Unit owner, float x, float y, float angle){ super(type, owner, angle); - set(x, y); this.type = type; + this.team = owner.team; + set(x, y); + } + + public Bullet(BulletType type, Entity owner, Team team, float x, float y, float angle){ + super(type, owner, angle); + this.team = team; + this.type = type; + set(x, y); + } + + public Bullet(BulletType type, Bullet parent, float x, float y, float angle){ + this(type, parent.owner, parent.team, x, y, angle); } public void draw(){ @@ -39,14 +53,6 @@ public class Bullet extends BulletEntity{ return true; } - public Unit owner(){ - return (Unit)owner; - } - - public Team team(){ - return ((Unit)owner).team; - } - @Override public void update(){ super.update(); @@ -58,7 +64,7 @@ public class Bullet extends BulletEntity{ if (tile == null) return false; tile = tile.target(); - if (tile.entity != null && tile.entity.collide(this) && !tile.entity.dead && tile.entity.tile.getTeam() != team()) { + if (tile.entity != null && tile.entity.collide(this) && !tile.entity.dead && tile.entity.tile.getTeam() != team) { tile.entity.collision(this); remove(); type.hit(this); diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 91d0572655..6daceb485f 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -121,7 +121,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shellexplosion, b); - DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f)); + DamageArea.damage(b.team, b.x, b.y, 25f, (int)(damage * 2f/3f)); } }, flak = new BulletType(2.9f, 8) { @@ -148,7 +148,7 @@ public abstract class BulletType extends BaseBulletType{ public void hit(Bullet b, float hitx, float hity) { Effects.effect(shellsmoke, b); for(int i = 0; i < 3; i ++){ - Bullet bullet = new Bullet(flakspark, b.owner(), hitx, hity, b.angle() + Mathf.range(120f)); + Bullet bullet = new Bullet(flakspark, b, hitx, hity, b.angle() + Mathf.range(120f)); bullet.add(); } } @@ -201,7 +201,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shockwaveSmall, b); - DamageArea.damage(b.team(), b.x, b.y, 50f, (int)(damage * 2f/3f)); + DamageArea.damage(b.team, b.x, b.y, 50f, (int)(damage * 2f/3f)); } }, yellowshell = new BulletType(1.2f, 20){ @@ -232,7 +232,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shockwaveSmall, b); - DamageArea.damage(b.team(), b.x, b.y, 25f, (int)(damage * 2f/3f)); + DamageArea.damage(b.team, b.x, b.y, 25f, (int)(damage * 2f/3f)); } }, blast = new BulletType(1.1f, 90){ @@ -255,7 +255,7 @@ public abstract class BulletType extends BaseBulletType{ //TODO remove translation() usage Angles.circleVectors(30, 6f, (nx, ny) -> { float ang = Mathf.atan2(nx, ny); - Bullet o = new Bullet(blastshot, b.owner(), b.x + nx, b.y + ny, ang).add(); + Bullet o = new Bullet(blastshot, b, b.x + nx, b.y + ny, ang).add(); o.damage = b.damage/9; }); } @@ -370,7 +370,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.clusterbomb, b); - DamageArea.damage(b.team(), b.x, b.y, 35f, damage); + DamageArea.damage(b.team, b.x, b.y, 35f, damage); } }, vulcan = new BulletType(4.5f, 12) { @@ -419,7 +419,7 @@ public abstract class BulletType extends BaseBulletType{ public void hit(Bullet b, float hitx, float hity) { for(int i = 0; i < 4; i ++){ - Bullet bullet = new Bullet(scrap, b.owner(), b.x, b.y, b.angle() + Mathf.range(80f)); + Bullet bullet = new Bullet(scrap, b, b.x, b.y, b.angle() + Mathf.range(80f)); bullet.add(); } } @@ -449,7 +449,7 @@ public abstract class BulletType extends BaseBulletType{ } public void init(Bullet b) { - DamageArea.damageLine(b.team(), Fx.beamhit, b.x, b.y, b.angle(), length, damage); + DamageArea.damageLine(b.team, Fx.beamhit, b.x, b.y, b.angle(), length, damage); } public void draw(Bullet b) { diff --git a/core/src/io/anuke/mindustry/game/Tutorial.java b/core/src/io/anuke/mindustry/game/Tutorial.java index 4a69aaa57d..4bef5c1bac 100644 --- a/core/src/io/anuke/mindustry/game/Tutorial.java +++ b/core/src/io/anuke/mindustry/game/Tutorial.java @@ -4,7 +4,6 @@ import com.badlogic.gdx.math.GridPoint2; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.*; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.builders.button; @@ -70,11 +69,12 @@ public class Tutorial{ //info.setText(stage.text); if(stage.showBlock){ + /* Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY); if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){ move(true); - } + }*/ } } @@ -287,6 +287,7 @@ public class Tutorial{ } void onSwitch(){ + /* for(int flip : new int[]{1, -1}){ world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); @@ -295,7 +296,7 @@ public class Tutorial{ world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone); world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill); - } + }*/ } }, deleteBlock{ @@ -342,7 +343,7 @@ public class Tutorial{ void onSwitch(){ for(int i = 0; i < 4; i ++){ - world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1); + //world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1); } control.input().recipe = null; @@ -428,7 +429,7 @@ public class Tutorial{ void onSwitch(){ ui.find("sectionbuttondistribution").fireClick(); - world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); + //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, conduitUse2{ @@ -444,7 +445,7 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); + //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, conduitUse3{ @@ -460,7 +461,7 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); + //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, generator{ @@ -475,7 +476,7 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); + //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); ui.find("sectionbuttonpower").fireClick(); state.inventory.addItem(Item.steel, 60); state.inventory.addItem(Item.iron, 60); @@ -558,6 +559,7 @@ public class Tutorial{ } void onSwitch(){ + /* for(int i = 0; i < 5; i ++){ world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1); } @@ -570,7 +572,7 @@ public class Tutorial{ world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill); world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2); - world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0); + world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0);*/ } }, tunnelExplain{ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index dd141b35d0..5253c3e664 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Tile; @@ -188,10 +187,6 @@ public class BlockRenderer{ Graphics.begin(); Draw.reset(); - - if(showPaths && debug){ - drawPaths(); - } if(debug && debugChunks){ Draw.color(Color.YELLOW); @@ -209,21 +204,6 @@ public class BlockRenderer{ Draw.reset(); } } - - void drawPaths(){ - Draw.color(Color.RED); - for(SpawnPoint point : world.getSpawns()){ - if(point.pathTiles != null){ - for(int i = 1; i < point.pathTiles.length; i ++){ - Lines.line(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(), - point.pathTiles[i].worldx(), point.pathTiles[i].worldy()); - Lines.circle(point.pathTiles[i-1].worldx(), point.pathTiles[i-1].worldy(), 6f); - } - } - } - Draw.reset(); - } - void drawCache(DrawLayer layer, int crangex, int crangey){ Gdx.gl.glEnable(GL20.GL_BLEND); diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 689a94ccea..2335a6225a 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -78,13 +78,13 @@ public abstract class InputHandler extends InputAdapter{ if(!type.isMultiblock() && control.tutorial().active() && control.tutorial().showBlock()){ - + + //TODO placepoint control, make sure it's correct. GridPoint2 point = control.tutorial().getPlacePoint(); int rotation = control.tutorial().getPlaceRotation(); Block block = control.tutorial().getPlaceBlock(); - if(type != block || point.x != x - world.getCore().x || point.y != y - world.getCore().y - || (rotation != -1 && rotation != this.rotation)){ + if(type != block || (rotation != -1 && rotation != this.rotation)){ return false; } }else if(control.tutorial().active()){ @@ -98,11 +98,12 @@ public abstract class InputHandler extends InputAdapter{ if(control.tutorial().active()){ if(control.tutorial().showBlock()){ + //TODO placepoint control, make sure it's correct GridPoint2 point = control.tutorial().getPlacePoint(); int rotation = control.tutorial().getPlaceRotation(); Block block = control.tutorial().getPlaceBlock(); - if(block != Blocks.air || point.x != x - world.getCore().x || point.y != y - world.getCore().y + if(block != Blocks.air || (rotation != -1 && rotation != this.rotation)){ return false; } diff --git a/core/src/io/anuke/mindustry/io/Map.java b/core/src/io/anuke/mindustry/io/Map.java new file mode 100644 index 0000000000..2f15f897d3 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/Map.java @@ -0,0 +1,20 @@ +package io.anuke.mindustry.io; + +import com.badlogic.gdx.graphics.Texture; + +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; + /**Preview texture.*/ + public Texture texture; + + public Map(String name, MapMeta meta, boolean custom){ + this.name = name; + this.custom = custom; + this.meta = meta; + } +} diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index bf04926d2b..b18792a437 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -3,4 +3,6 @@ package io.anuke.mindustry.io; /**Reads and writes map files.*/ public class MapIO { //TODO implementation + + } diff --git a/core/src/io/anuke/mindustry/io/MapMeta.java b/core/src/io/anuke/mindustry/io/MapMeta.java new file mode 100644 index 0000000000..b9e1b4abd7 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/MapMeta.java @@ -0,0 +1,32 @@ +package io.anuke.mindustry.io; + +import com.badlogic.gdx.utils.ObjectMap; + +public class MapMeta { + public final int version; + public final ObjectMap tags; + public final int width, height; + + public MapMeta(int version, ObjectMap tags, int width, int height) { + this.version = version; + this.tags = tags; + this.width = width; + this.height = height; + } + + 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", "1").equals("1"); + } +} diff --git a/core/src/io/anuke/mindustry/io/MapTileData.java b/core/src/io/anuke/mindustry/io/MapTileData.java new file mode 100644 index 0000000000..95f75b2d23 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/MapTileData.java @@ -0,0 +1,75 @@ +package io.anuke.mindustry.io; + +import io.anuke.ucore.util.Bits; + +import java.nio.ByteBuffer; + +public class MapTileData { + /**Tile size: 3 bytes. + * 0: ground tile + * 1: wall tile + * 2: rotation + team*/ + private final static int TILE_SIZE = 3; + + private final ByteBuffer buffer; + private final TileData tile = new TileData(); + private final int width, height; + + public MapTileData(int width, int height){ + this.width = width; + this.height = height; + buffer = ByteBuffer.allocate(width * height * TILE_SIZE); + } + + public MapTileData(byte[] bytes, int width, int height){ + buffer = ByteBuffer.wrap(bytes); + this.width = width; + this.height = height; + } + + public int width(){ + return width; + } + + public int height(){ + return height; + } + + /**Reads and returns the next tile data.*/ + public TileData read(){ + tile.read(); + return tile; + } + + /**Writes tile data at a specified position. Uses the tile data returned by read().*/ + public void write(int x, int y){ + position(x, y); + tile.write(); + } + + /**Sets read position to the specified coordinates*/ + public void position(int x, int y){ + buffer.position((x + width * y) * TILE_SIZE); + } + + public class TileData{ + public byte floor, wall; + public byte rotation; + public byte team; + + private void read(){ + floor = buffer.get(); + wall = buffer.get(); + byte rt = buffer.get(); + rotation = Bits.getLeftByte(rt); + team = Bits.getRightByte(rt); + } + + private void write(){ + buffer.put(floor); + buffer.put(wall); + byte rt = Bits.packByte(rotation, team); + buffer.put(rt); + } + } +} diff --git a/core/src/io/anuke/mindustry/io/Maps.java b/core/src/io/anuke/mindustry/io/Maps.java index ad41c3f431..92b23ecb94 100644 --- a/core/src/io/anuke/mindustry/io/Maps.java +++ b/core/src/io/anuke/mindustry/io/Maps.java @@ -1,224 +1,89 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.utils.*; -import com.badlogic.gdx.utils.Json.Serializer; -import com.badlogic.gdx.utils.JsonWriter.OutputType; -import io.anuke.mindustry.world.Map; -import io.anuke.ucore.core.Settings; -import io.anuke.ucore.graphics.Pixmaps; -import io.anuke.ucore.util.Log; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.ObjectMap; -import static io.anuke.mindustry.Vars.*; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +import static io.anuke.mindustry.Vars.customMapDirectory; +import static io.anuke.mindustry.Vars.mapExtension; public class Maps implements Disposable{ - private IntMap maps = new IntMap<>(); - private ObjectMap mapNames = new ObjectMap<>(); + private ObjectMap maps = new ObjectMap<>(); + private Array allMaps = new Array<>(); + private Array customMaps = new Array<>(); private Array defaultMaps = new Array<>(); - private Map networkMap; - private int lastID; - private Json json = new Json(); - private Array array = new Array<>(); - public Maps() { - json.setOutputType(OutputType.json); - json.setElementType(ArrayContainer.class, "maps", Map.class); - json.setSerializer(Color.class, new ColorSerializer()); + public void load(){ + //TODO } - public Iterable list(){ - return maps.values(); + public void save(){ + //TODO? } - public Array getDefaultMaps(){ - return defaultMaps; + /**Returns a list of all maps, including custom ones.*/ + public Array all(){ + return allMaps; } - public Array getCustomMaps(){ - array.clear(); - for(Map map : list()){ - if(map.custom) array.add(map); - } - return array; + /**Returns map by internal name.*/ + public Map getByName(String name){ + return maps.get(name); } - public Array getAllMaps(){ - array.clear(); - for(Map map : list()){ - array.add(map); - } - return array; - } - - public void setNetworkMap(Map map){ - if(networkMap != null){ - networkMap.pixmap.dispose(); - networkMap = null; - } - - networkMap = map; - } - - public Map getMap(int id){ - if(id == -1){ - return networkMap; - } - return maps.get(id); - } - - public Map getMap(String name){ - return mapNames.get(name); - } - - public void loadMaps(){ - if(!loadMapFile(Gdx.files.internal("maps/maps.json"), true)){ - throw new RuntimeException("Failed to load maps!"); - } - - if(!gwt) { - if (!loadMapFile(customMapDirectory.child("maps.json"), false)) { - try { - Log.info("Failed to find custom map directory."); - customMapDirectory.child("maps.json").writeString("{}", false); - } catch (Exception e) { - throw new RuntimeException("Failed to create custom map directory!"); - } - } - } - } - - public void removeMap(Map map){ - maps.remove(map.id); - mapNames.remove(map.name); - Array out = new Array<>(); - for(Map m : maps.values()){ - if(m.custom){ - out.add(m); - } - } - saveMaps(out, customMapDirectory.child("maps.json")); - } - - public void saveAndReload(Map map, Pixmap out){ - if(map.pixmap != null && out != map.pixmap && map.texture != null){ - map.texture.dispose(); - map.texture = new Texture(out); - }else if (out == map.pixmap){ - map.texture.draw(out, 0, 0); - } - - map.pixmap = out; - if(map.texture == null) map.texture = new Texture(map.pixmap); - - if(map.id == -1){ - if(mapNames.containsKey(map.name)){ - map.id = mapNames.get(map.name).id; - }else{ - map.id = ++lastID; - } - } - - if(!Settings.has("hiscore" + map.name)){ - Settings.defaults("hiscore" + map.name, 0); - } - - saveCustomMap(map); - ui.levels.reload(); - } - - public void saveMaps(Array array, FileHandle file){ - json.toJson(new ArrayContainer(array), file); - } - - public void saveCustomMap(Map toSave){ - toSave.custom = true; - Array out = new Array<>(); - boolean added = false; - for(Map map : maps.values()){ - if(map.custom){ - if(map.name.equals(toSave.name)){ - out.add(toSave); - toSave.id = map.id; - added = true; - }else{ - out.add(map); - } - } - } - if(!added){ - out.add(toSave); - } - maps.remove(toSave.id); - mapNames.remove(toSave.name); - maps.put(toSave.id, toSave); - mapNames.put(toSave.name, toSave); - Pixmaps.write(toSave.pixmap, customMapDirectory.child(toSave.name + ".png")); - saveMaps(out, customMapDirectory.child("maps.json")); - } - - private boolean loadMapFile(FileHandle file, boolean logException){ + //TODO GWT support: read from prefs string if custom + public MapTileData readTileData(Map map){ try { - Array arr = json.fromJson(ArrayContainer.class, file).maps; - if (arr != null) { //can be an empty map file - for (Map map : arr) { - map.pixmap = new Pixmap(file.sibling(map.name + ".png")); - if (!headless) map.texture = new Texture(map.pixmap); - maps.put(map.id, map); - mapNames.put(map.name, map); - lastID = Math.max(lastID, map.id); - if (!map.custom) { - defaultMaps.add(map); - } - } + InputStream stream; + + if (map.custom) { + stream = Gdx.files.local("maps/" + map.name + "." + mapExtension).read(); + } else { + stream = customMapDirectory.child(map.name + "." + mapExtension).read(); } - return true; - }catch (GdxRuntimeException e){ - Log.err(e); - return true; - }catch(Exception e){ - if(logException) { - Log.err(e); - Log.err("Failed loading map file: {0}", file); - } - return false; + + DataInputStream ds = new DataInputStream(stream); + MapTileData data = readTileData(ds); + ds.close(); + return data; + }catch (IOException e){ + throw new RuntimeException(e); } } + private MapTileData readTileData(DataInputStream stream) throws IOException{ + MapMeta meta = readMapMeta(stream); + byte[] bytes = new byte[stream.available()]; + stream.read(bytes); + return new MapTileData(bytes, meta.width, meta.height); + } + + private MapMeta readMapMeta(DataInputStream stream) throws IOException{ + ObjectMap tags = new ObjectMap<>(); + + int version = stream.readInt(); + + byte tagAmount = stream.readByte(); + + for(int i = 0; i < tagAmount; i ++){ + String name = stream.readUTF(); + String value = stream.readUTF(); + tags.put(name, value); + } + + int width = stream.readShort(); + int height = stream.readShort(); + + return new MapMeta(version, tags, width, height); + } + @Override - public void dispose(){ - for(Map map : maps.values()){ - if(map.texture != null) map.texture.dispose(); - map.pixmap.dispose(); - } - maps.clear(); - } - - public static class ArrayContainer{ - Array maps; - - public ArrayContainer() { - } - - public ArrayContainer(Array maps) { - this.maps = maps; - } - } - - private class ColorSerializer implements Serializer{ - - @Override - public void write(Json json, Color object, Class knownType){ - json.writeValue(object.toString().substring(0, 6)); - } - - @Override - public Color read(Json json, JsonValue jsonData, Class type){ - return Color.valueOf(jsonData.asString()); - } + public void dispose() { } } diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index 38cbdec31a..1a0d94bde9 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -16,9 +16,10 @@ public abstract class SaveFileVersion { public SaveMeta getData(DataInputStream stream) throws IOException{ long time = stream.readLong(); //read last saved time byte mode = stream.readByte(); //read the gamemode - byte map = stream.readByte(); //read the map + String map = stream.readUTF(); //read the map int wave = stream.readInt(); //read the wave - return new SaveMeta(version, time, mode, map, wave, Difficulty.normal); + byte difficulty = stream.readByte(); //read the difficulty + return new SaveMeta(version, time, mode, map, wave, Difficulty.values()[difficulty]); } public abstract void read(DataInputStream stream) throws IOException; diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 00ac323ab9..a8553a302c 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -79,8 +79,8 @@ public class SaveIO{ try{ int version = stream.readInt(); SaveFileVersion ver = versions.get(version); - SaveMeta meta = ver.getData(stream); - return meta.map != null; + ver.getData(stream); + return true; }catch (Exception e){ return false; } diff --git a/core/src/io/anuke/mindustry/io/SaveMeta.java b/core/src/io/anuke/mindustry/io/SaveMeta.java index 277a7dca1e..4146c65812 100644 --- a/core/src/io/anuke/mindustry/io/SaveMeta.java +++ b/core/src/io/anuke/mindustry/io/SaveMeta.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.io; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.world.Map; import java.util.Date; @@ -16,11 +15,11 @@ public class SaveMeta { public int wave; public Difficulty difficulty; - public SaveMeta(int version, long date, int mode, int map, int wave, Difficulty difficulty){ + public SaveMeta(int version, long date, int mode, String map, int wave, Difficulty difficulty){ this.version = version; this.date = Platform.instance.format(new Date(date)); this.mode = GameMode.values()[mode]; - this.map = world.maps().getMap(map); + this.map = world.maps().getByName(map); this.wave = wave; this.difficulty = difficulty; } diff --git a/core/src/io/anuke/mindustry/io/Saves.java b/core/src/io/anuke/mindustry/io/Saves.java index 95bb189d08..031f08cae0 100644 --- a/core/src/io/anuke/mindustry/io/Saves.java +++ b/core/src/io/anuke/mindustry/io/Saves.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.async.AsyncExecutor; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.world.Map; import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 2d4c03922e..73bf0f3672 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -8,18 +8,16 @@ import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.SaveFileVersion; -import io.anuke.mindustry.io.SaveMeta; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.WorldGenerator; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.BlockPart; -import io.anuke.mindustry.world.blocks.types.Rock; import io.anuke.ucore.core.Core; import io.anuke.ucore.entities.EntityGroup; +import io.anuke.ucore.util.Bits; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -34,16 +32,6 @@ public class Save16 extends SaveFileVersion { super(16); } - public SaveMeta getData(DataInputStream stream) throws IOException{ - long time = stream.readLong(); //read last saved time - byte mode = stream.readByte(); //read the gamemode - byte map = stream.readByte(); //read the map - int wave = stream.readInt(); //read the wave - stream.readFloat(); //wave time - byte difficulty = stream.readByte(); - return new SaveMeta(version, time, mode, map, wave, Difficulty.values()[difficulty]); - } - @Override public void read(DataInputStream stream) throws IOException { /*long loadTime = */ @@ -51,11 +39,11 @@ public class Save16 extends SaveFileVersion { //general state byte mode = stream.readByte(); - byte mapid = stream.readByte(); + String mapname = stream.readUTF(); int wave = stream.readInt(); - float wavetime = stream.readFloat(); byte difficulty = stream.readByte(); + float wavetime = stream.readFloat(); state.difficulty = Difficulty.values()[difficulty]; @@ -148,62 +136,44 @@ public class Save16 extends SaveFileVersion { //map - int seed = stream.readInt(); + short width = stream.readShort(); + short height = stream.readShort(); - world.loadMap(world.maps().getMap(mapid), seed); - if(!headless) renderer.clearTiles(); - - int rocks = stream.readInt(); + Tile[][] tiles = world.createTiles(width, height); for(int x = 0; x < world.width(); x ++){ - for(int y = 0; y < world.height(); y ++){ - Tile tile = world.tile(x, y); + for(int y = 0; y < world.height(); y ++) { + byte floorid = stream.readByte(); + byte wallid = stream.readByte(); - //remove breakables like rocks - if(tile.breakable()){ - world.tile(x, y).setBlock(Blocks.air); + Tile tile = new Tile(x, y, floorid, wallid); + + if (wallid == Blocks.blockpart.id) { + tile.link = stream.readByte(); } + + if (tile.entity != null) { + byte tr = stream.readByte(); + byte team = Bits.getLeftByte(tr); + byte rotation = Bits.getRightByte(tr); + short health = stream.readShort(); + + tile.setTeam(Team.values()[team]); + tile.entity.health = health; + tile.setRotation(rotation); + + if (tile.entity.inventory != null) tile.entity.inventory.read(stream); + if (tile.entity.power != null) tile.entity.power.read(stream); + if (tile.entity.liquid != null) tile.entity.liquid.read(stream); + + tile.entity.read(stream); + } + + tiles[x][y] = tile; } } - for(int i = 0; i < rocks; i ++){ - int pos = stream.readInt(); - Tile tile = world.tile(pos % world.width(), pos / world.width()); - if(tile == null) continue; - Block result = WorldGenerator.rocks.get(tile.floor()); - if(result != null) tile.setBlock(result); - } - - int tiles = stream.readInt(); - - for(int i = 0; i < tiles; i ++){ - int pos = stream.readInt(); - int blockid = stream.readInt(); - - Tile tile = world.tile(pos % world.width(), pos / world.width()); - - tile.setBlock(map.get(blockid)); - - if(blockid == Blocks.blockpart.id){ - tile.link = stream.readByte(); - } - - if(tile.entity != null){ - byte team = stream.readByte(); - byte rotation = stream.readByte(); - short health = stream.readShort(); - - tile.setTeam(Team.values()[team]); - tile.entity.health = health; - tile.setRotation(rotation); - - if(tile.entity.inventory != null) tile.entity.inventory.read(stream); - if(tile.entity.power != null) tile.entity.power.read(stream); - if(tile.entity.liquid != null) tile.entity.liquid.read(stream); - - tile.entity.read(stream); - } - } + if(!headless) renderer.clearTiles(); } @Override @@ -214,11 +184,11 @@ public class Save16 extends SaveFileVersion { //--GENERAL STATE-- stream.writeByte(state.mode.ordinal()); //gamemode - stream.writeByte(world.getMap().id); //map ID + stream.writeUTF(world.getMap().name); //map ID stream.writeInt(state.wave); //wave + stream.writeByte(state.difficulty.ordinal()); //difficulty ordinal stream.writeFloat(state.wavetime); //wave countdown - stream.writeByte(state.difficulty.ordinal()); //--BLOCK HEADER-- @@ -286,65 +256,31 @@ public class Save16 extends SaveFileVersion { //--MAP DATA-- - //seed - stream.writeInt(world.getSeed()); - - int totalblocks = 0; - int totalrocks = 0; + //write world size + stream.writeShort(world.width()); + stream.writeShort(world.height()); + //now write all blocks for(int x = 0; x < world.width(); x ++){ for(int y = 0; y < world.height(); y ++){ Tile tile = world.tile(x, y); - if(tile != null && tile.breakable()){ - if(tile.block() instanceof Rock){ - totalrocks ++; - }else{ - totalblocks ++; - } + stream.writeByte(tile.floor().id); //floor ID + stream.writeByte(tile.block().id); //wall ID + + if(tile.block() instanceof BlockPart){ + stream.writeByte(tile.link); } - } - } - //amount of rocks - stream.writeInt(totalrocks); + if(tile.entity != null){ + stream.writeByte(Bits.packByte((byte)tile.getTeam().ordinal(), tile.getRotation())); //team + rotation + stream.writeShort((short)tile.entity.health); //health - //write all rocks - for(int x = 0; x < world.width(); x ++) { - for (int y = 0; y < world.height(); y++) { - Tile tile = world.tile(x, y); + if(tile.entity.inventory != null) tile.entity.inventory.write(stream); + if(tile.entity.power != null) tile.entity.power.write(stream); + if(tile.entity.liquid != null) tile.entity.liquid.write(stream); - if (tile != null && tile.block() instanceof Rock) { - stream.writeInt(tile.packedPosition()); - } - } - } - - //write all blocks - stream.writeInt(totalblocks); - - for(int x = 0; x < world.width(); x ++){ - for(int y = 0; y < world.height(); y ++){ - Tile tile = world.tile(x, y); - - if(tile != null && tile.breakable() && !(tile.block() instanceof Rock)){ - - stream.writeInt(x + y*world.width()); //tile pos - stream.writeInt(tile.block().id); //block ID - - if(tile.block() instanceof BlockPart) stream.writeByte(tile.link); - - if(tile.entity != null){ - stream.writeByte(tile.getTeam().ordinal()); - stream.writeByte(tile.getRotation()); //rotation - stream.writeShort((short)tile.entity.health); //health - - if(tile.entity.inventory != null) tile.entity.inventory.write(stream); - if(tile.entity.power != null) tile.entity.power.write(stream); - if(tile.entity.liquid != null) tile.entity.liquid.write(stream); - - tile.entity.write(stream); - } + tile.entity.write(stream); } } } diff --git a/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java b/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java deleted file mode 100755 index 5884250cd5..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.utils.Disposable; -import io.anuke.ucore.graphics.Pixmaps; - -public class DrawOperation implements Disposable{ - Pixmap from, to, pixmap; - - public DrawOperation(Pixmap pixmap){ - this.pixmap = pixmap; - } - - public void add(Pixmap from, Pixmap to) { - this.from = from; - this.to = to; - } - - public void undo() { - if(from != null) pixmap.drawPixmap(from, 0, 0); - } - - public void redo() { - if(to != null) pixmap.drawPixmap(to, 0, 0); - } - - @Override - public void dispose() { - if(!Pixmaps.isDisposed(from)) - from.dispose(); - - if(!Pixmaps.isDisposed(to)) - to.dispose(); - } - - public void disposeFrom(){ - if(from != null) from.dispose(); - } - -} diff --git a/core/src/io/anuke/mindustry/mapeditor/EditorTool.java b/core/src/io/anuke/mindustry/mapeditor/EditorTool.java deleted file mode 100644 index 561a9abf42..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/EditorTool.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.math.GridPoint2; -import com.badlogic.gdx.utils.IntSet; -import static io.anuke.mindustry.Vars.*; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.ColorMapper.BlockPair; - -import java.util.Stack; - -public enum EditorTool{ - pick{ - public void touched(MapEditor editor, int x, int y){ - BlockPair pair = ColorMapper.get(editor.pixmap().getPixel(x, y)); - if(pair == null) return; - Block block = pair.dominant(); - editor.setDrawBlock(block); - ui.editor.updateSelectedBlock(); - } - }, - pencil{ - { - edit = true; - } - - public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y); - } - }, - line{ - { - - } - - }, - fill{ - { - edit = true; - } - - public void touched(MapEditor editor, int x, int y){ - Pixmap pix = editor.pixmap(); - - int dest = pix.getPixel(x, y); - - int width = pix.getWidth(); - - IntSet set = new IntSet(); - Stack points = new Stack(); - points.add(new GridPoint2(x, y)); - - while( !points.isEmpty()){ - GridPoint2 pos = points.pop(); - set.add(asInt(pos.x, pos.y, width)); - - int pcolor = pix.getPixel(pos.x, pos.y); - if(colorEquals(pcolor, dest)){ - - pix.drawPixel(pos.x, pos.y); - - if(pos.x > 0 && !set.contains(asInt(pos.x - 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add( -1, 0)); - if(pos.y > 0 && !set.contains(asInt(pos.x, pos.y - 1, width))) points.add(new GridPoint2(pos).cpy().add(0, -1)); - if(pos.x < pix.getWidth() - 1 && !set.contains(asInt(pos.x + 1, pos.y, width))) points.add(new GridPoint2(pos).cpy().add(1, 0)); - if(pos.y < pix.getHeight() - 1 && !set.contains(asInt(pos.x, pos.y + 1, width))) points.add(new GridPoint2(pos).cpy().add(0, 1)); - } - } - - editor.updateTexture(); - } - - int asInt(int x, int y, int width){ - return x+y*width; - } - - boolean colorEquals(int a, int b){ - return a == b; - } - }, - zoom; - boolean edit; - - public void touched(MapEditor editor, int x, int y){ - - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java deleted file mode 100644 index 7ef8f97a47..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java +++ /dev/null @@ -1,201 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.Map; -import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.ucore.graphics.Pixmaps; - -public class MapEditor{ - public static final int[] validMapSizes = {128, 256, 512}; - public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; - public static final int maxSpawnpoints = 15; - public static final Format format = Format.RGBA8888; - - private Pixmap[] brushPixmaps = new Pixmap[brushSizes.length]; - - private Map map; - - private MapFilter filter = new MapFilter(); - private Pixmap filterPixmap; - private Texture filterTexture; - - private Pixmap pixmap; - private Texture texture; - private int brushSize = 1; - private Block drawBlock = Blocks.stone; - - public MapEditor(){ - for(int i = 0; i < brushSizes.length; i ++){ - int s = brushSizes[i]; - brushPixmaps[i] = new Pixmap(s*2-1, s*2-1, format); - } - } - - public Map getMap(){ - return map; - } - - public void updateTexture(){ - texture.draw(pixmap, 0, 0); - } - - public MapFilter getFilter(){ - return filter; - } - - public void applyFilterPreview(){ - if(filterPixmap != null && (filterPixmap.getWidth() != pixmap.getWidth() - || filterPixmap.getHeight() != pixmap.getHeight())){ - filterPixmap.dispose(); - filterTexture.dispose(); - filterPixmap = null; - filterTexture = null; - } - - if(filterPixmap == null){ - filterPixmap = Pixmaps.copy(pixmap); - - filter.process(filterPixmap); - filterTexture = new Texture(filterPixmap); - }else{ - filterPixmap.drawPixmap(pixmap, 0, 0); - filter.process(filterPixmap); - filterTexture.draw(filterPixmap, 0, 0); - } - - } - - public Texture getFilterTexture(){ - return filterTexture; - } - - public void applyFilter(){ - filter.process(pixmap); - texture.draw(pixmap, 0, 0); - } - - public void beginEdit(Map map){ - drawBlock = Blocks.stone; - this.map = map; - this.brushSize = 1; - if(map.pixmap == null){ - pixmap = new Pixmap(256, 256, format); - pixmap.setColor(ColorMapper.getColor(drawBlock)); - pixmap.fill(); - texture = new Texture(pixmap); - }else{ - pixmap = map.pixmap; - texture = map.texture; - pixmap.setColor(ColorMapper.getColor(drawBlock)); - } - - } - - public Block getDrawBlock(){ - return drawBlock; - } - - public void setDrawBlock(Block block){ - this.drawBlock = block; - pixmap.setColor(ColorMapper.getColor(block)); - } - - public void setBrushSize(int size){ - this.brushSize = size; - } - - public int getBrushSize() { - return brushSize; - } - - public void draw(int dx, int dy){ - if(dx < 0 || dy < 0 || dx >= pixmap.getWidth() || dy >= pixmap.getHeight()){ - return; - } - - Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, texture.getTextureObjectHandle()); - - int dstWidth = brushSize*2-1; - int dstHeight = brushSize*2-1; - int width = pixmap.getWidth(), height = pixmap.getHeight(); - - int x = dx - dstWidth/2; - int y = dy - dstHeight/2; - - if (x + dstWidth > width){ - x = width - dstWidth; - }else if (x < 0){ - x = 0; - } - - if (y + dstHeight > height){ - dstHeight = height - y; - }else if (y < 0){ - dstHeight += y; - y = 0; - } - - pixmap.fillCircle(dx, dy, brushSize-1); - - Pixmap dst = brush(brushSize); - dst.drawPixmap(pixmap, x, y, dstWidth, dstHeight, 0, 0, dstWidth, dstHeight); - - Gdx.gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, x, y, dstWidth, dstHeight, - dst.getGLFormat(), dst.getGLType(), dst.getPixels()); - } - - private Pixmap brush(int size){ - for(int i = 0; i < brushSizes.length; i ++){ - if(brushSizes[i] == size){ - return brushPixmaps[i]; - } - } - return null; - } - - public Texture texture(){ - return texture; - } - - public Pixmap pixmap(){ - return pixmap; - } - - public void setPixmap(Pixmap out){ - if(pixmap.getWidth() == out.getWidth() && pixmap.getHeight() == out.getHeight()){ - pixmap.dispose(); - pixmap = out; - texture.draw(out, 0, 0); - }else{ - pixmap.dispose(); - texture.dispose(); - pixmap = out; - texture = new Texture(out); - } - pixmap.setColor(ColorMapper.getColor(drawBlock)); - map.pixmap = pixmap; - map.texture = texture; - } - - public void resize(int width, int height){ - Pixmap out = Pixmaps.resize(pixmap, width, height, ColorMapper.getColor(Blocks.stone)); - pixmap.dispose(); - pixmap = out; - texture.dispose(); - texture = new Texture(out); - - if(filterPixmap != null){ - filterPixmap.dispose(); - filterTexture.dispose(); - filterPixmap = null; - filterTexture = null; - } - pixmap.setColor(ColorMapper.getColor(drawBlock)); - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java deleted file mode 100644 index 79ce0e18f8..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java +++ /dev/null @@ -1,439 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import io.anuke.mindustry.io.Platform; -import io.anuke.mindustry.ui.dialogs.FileChooser; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.ColorMapper.BlockPair; -import io.anuke.mindustry.world.Map; -import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.SpecialBlocks; -import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Inputs; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Pixmaps; -import io.anuke.ucore.scene.Element; -import io.anuke.ucore.scene.builders.build; -import io.anuke.ucore.scene.builders.imagebutton; -import io.anuke.ucore.scene.builders.label; -import io.anuke.ucore.scene.builders.table; -import io.anuke.ucore.scene.ui.*; -import io.anuke.ucore.scene.ui.layout.Table; -import io.anuke.ucore.util.Bundles; -import io.anuke.ucore.util.Log; -import io.anuke.ucore.util.Strings; - -import java.util.Arrays; - -import static io.anuke.mindustry.Vars.*; - -public class MapEditorDialog extends Dialog{ - private MapEditor editor; - private MapView view; - private MapGenerateDialog dialog; - private MapLoadDialog loadDialog; - private MapSaveDialog saveDialog; - private MapResizeDialog resizeDialog; - private ScrollPane pane; - private FileChooser openFile, saveFile; - private boolean saved = false; - - private ButtonGroup blockgroup; - - public MapEditorDialog(){ - super("$text.mapeditor", "dialog"); - if(gwt) return; - - editor = new MapEditor(); - dialog = new MapGenerateDialog(editor); - view = new MapView(editor); - - openFile = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> { - ui.loadfrag.show(); - Timers.run(3f, () -> { - try{ - Pixmap pixmap = new Pixmap(file); - if(verifySize(pixmap)){ - editor.setPixmap(pixmap); - view.clearStack(); - }else{ - ui.showError(Bundles.format("text.editor.badsize", Arrays.toString(MapEditor.validMapSizes))); - } - }catch (Exception e){ - ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); - Log.err(e); - } - ui.loadfrag.hide(); - }); - }); - - saveFile = new FileChooser("$saveimage", false, file -> { - if(!file.extension().toLowerCase().equals(".png")){ - file = file.parent().child(file.nameWithoutExtension() + ".png"); - } - FileHandle result = file; - ui.loadfrag.show(); - Timers.run(3f, () -> { - try{ - Pixmaps.write(editor.pixmap(), result); - }catch (Exception e){ - ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); - if(!android) Log.err(e); - } - ui.loadfrag.hide(); - }); - }); - - loadDialog = new MapLoadDialog(map -> { - saveDialog.setFieldText(map.name); - ui.loadfrag.show(); - - Timers.run(3f, () -> { - Map copy = new Map(); - copy.name = map.name; - copy.id = -1; - copy.pixmap = Pixmaps.copy(map.pixmap); - copy.texture = new Texture(copy.pixmap); - copy.oreGen = map.oreGen; - editor.beginEdit(copy); - ui.loadfrag.hide(); - view.clearStack(); - }); - }); - - resizeDialog = new MapResizeDialog(editor, (x, y) -> { - Pixmap pix = editor.pixmap(); - if(!(pix.getWidth() == x && pix.getHeight() == y)){ - ui.loadfrag.show(); - Timers.run(10f, ()->{ - editor.resize(x, y); - view.clearStack(); - ui.loadfrag.hide(); - }); - } - }); - - saveDialog = new MapSaveDialog(name -> { - ui.loadfrag.show(); - if(verifyMap()){ - saved = true; - String before = editor.getMap().name; - editor.getMap().name = name; - Timers.run(10f, () -> { - world.maps().saveAndReload(editor.getMap(), editor.pixmap()); - loadDialog.rebuild(); - ui.loadfrag.hide(); - view.clearStack(); - - if(!name.equals(before)) { - Map map = new Map(); - map.name = editor.getMap().name; - map.oreGen = editor.getMap().oreGen; - map.pixmap = Pixmaps.copy(editor.getMap().pixmap); - map.texture = new Texture(map.pixmap); - map.custom = true; - editor.beginEdit(map); - } - }); - - }else{ - ui.loadfrag.hide(); - } - }); - - setFillParent(true); - - clearChildren(); - margin(0); - build.begin(this); - build(); - build.end(); - - tapped(() -> { - Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); - if(e == null || !e.isDescendantOf(pane)) Core.scene.setScrollFocus(null); - }); - - update(() -> { - if(Core.scene != null && Core.scene.getKeyboardFocus() == this){ - doInput(); - } - }); - - shown(() -> { - saved = true; - editor.beginEdit(new Map()); - blockgroup.getButtons().get(2).setChecked(true); - Core.scene.setScrollFocus(view); - view.clearStack(); - - Timers.runTask(10f, Platform.instance::updateRPC); - }); - - hidden(() -> Platform.instance.updateRPC()); - } - - public MapView getView() { - return view; - } - - public void resetSaved(){ - saved = false; - } - - public void updateSelectedBlock(){ - Block block = editor.getDrawBlock(); - int i = 0; - for(BlockPair pair : ColorMapper.getPairs()){ - if(pair.wall == block || (pair.wall == Blocks.air && pair.floor == block)){ - blockgroup.getButtons().get(i).setChecked(true); - break; - } - i++; - } - } - - public boolean hasPane(){ - return Core.scene.getScrollFocus() == pane; - } - - public void build(){ - - new table(){{ - float isize = 16*2f; - aleft(); - - new table(){{ - - defaults().growY().width(130f).padBottom(-6); - - new imagebutton("icon-terrain", isize, () -> - dialog.show() - ).text("$text.editor.generate"); - - row(); - - new imagebutton("icon-resize", isize, () -> - resizeDialog.show() - ).text("$text.editor.resize").padTop(4f); - - row(); - - new imagebutton("icon-load-map", isize, () -> - loadDialog.show() - ).text("$text.editor.loadmap"); - - row(); - - new imagebutton("icon-save-map", isize, ()-> - saveDialog.show() - ).text("$text.editor.savemap"); - - row(); - - new imagebutton("icon-load-image", isize, () -> - openFile.show() - ).text("$text.editor.loadimage"); - - row(); - - new imagebutton("icon-save-image", isize, () -> - saveFile.show() - ).text("$text.editor.saveimage"); - - row(); - - new imagebutton("icon-back", isize, () -> { - if(!saved){ - ui.showConfirm("$text.confirm", "$text.editor.unsaved", - MapEditorDialog.this::hide); - }else{ - hide(); - } - }).padBottom(0).text("$text.back"); - - }}.left().growY().end(); - - new table("button"){{ - add(view).grow(); - }}.grow().end(); - - new table(){{ - Table tools = new Table("button"); - tools.top(); - tools.marginTop(0).marginBottom(6); - - ButtonGroup group = new ButtonGroup<>(); - int i = 1; - - tools.defaults().size(53f, 58f).padBottom(-6); - - ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get(); - ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get(); - ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get(); - - undo.setDisabled(() -> !view.getStack().canUndo()); - redo.setDisabled(() -> !view.getStack().canRedo()); - - undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE)); - redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE)); - grid.update(() -> grid.setChecked(view.isGrid())); - - for(EditorTool tool : EditorTool.values()){ - ImageButton button = new ImageButton("icon-" + tool.name(), "toggle"); - button.clicked(() -> view.setTool(tool)); - button.resizeImage(16*2f); - button.update(() -> button.setChecked(view.getTool() == tool)); - group.add(button); - if (tool == EditorTool.pencil) - button.setChecked(true); - - tools.add(button).padBottom(-6f); - if(i++ % 4 == 1) tools.row(); - } - - add(tools).width(53*4).padBottom(-6); - - row(); - - new table("button"){{ - margin(10f); - Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false); - slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f])); - new label(() -> Bundles.format("text.editor.brushsize", MapEditor.brushSizes[(int)slider.getValue()])).left(); - row(); - add(slider).growX().padTop(4f); - }}.growX().padBottom(-6).end(); - - row(); - - new table("button"){{ - get().addCheck("$text.oregen", b -> editor.getMap().oreGen = b) - .update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3); - }}.growX().padBottom(-6).end(); - - row(); - - addBlockSelection(get()); - - row(); - - }}.right().growY().end(); - }}.grow().end(); - } - - private void doInput(){ - //tool select - for(int i = 0; i < EditorTool.values().length; i ++){ - int code = i == 0 ? 5 : i; - if(Inputs.keyTap("weapon_" + code)){ - view.setTool(EditorTool.values()[i]); - break; - } - } - - //ctrl keys (undo, redo, save) - if(Inputs.keyDown(Keys.CONTROL_LEFT)){ - if(Inputs.keyTap(Keys.Z)){ - view.undo(); - } - - if(Inputs.keyTap(Keys.Y)){ - view.redo(); - } - - if(Inputs.keyTap(Keys.S)){ - saveDialog.save(); - } - - if(Inputs.keyTap(Keys.G)){ - view.setGrid(!view.isGrid()); - } - } - } - - private boolean verifySize(Pixmap pix){ - boolean w = false, h = false; - for(int i : MapEditor.validMapSizes){ - if(pix.getWidth() == i) - w = true; - if(pix.getHeight() == i) - h = true; - } - - return w && h; - } - - private boolean verifyMap(){ - int psc = ColorMapper.getColor(SpecialBlocks.playerSpawn); - int esc = ColorMapper.getColor(SpecialBlocks.enemySpawn); - - int playerSpawns = 0; - int enemySpawns = 0; - Pixmap pix = editor.pixmap(); - - for(int x = 0; x < pix.getWidth(); x ++){ - for(int y = 0; y < pix.getHeight(); y ++){ - int i = pix.getPixel(x, y); - if(i == psc) playerSpawns ++; - if(i == esc) enemySpawns ++; - } - } - - if(playerSpawns == 0){ - ui.showError("$text.editor.noplayerspawn"); - return false; - }else if(playerSpawns > 1){ - ui.showError("$text.editor.manyplayerspawns"); - return false; - } - - if(enemySpawns > MapEditor.maxSpawnpoints){ - ui.showError(Bundles.format("text.editor.manyenemyspawns", MapEditor.maxSpawnpoints)); - return false; - } - - return true; - } - - private void addBlockSelection(Table table){ - Table content = new Table(); - pane = new ScrollPane(content, "volume"); - pane.setScrollingDisabled(true, false); - pane.setFadeScrollBars(false); - pane.setOverscroll(true, false); - ButtonGroup group = new ButtonGroup<>(); - blockgroup = group; - - int i = 0; - - for(BlockPair pair : ColorMapper.getPairs()){ - Block block = pair.wall == Blocks.air ? pair.floor : pair.wall; - - ImageButton button = new ImageButton(Draw.hasRegion(block.name) ? Draw.region(block.name) : Draw.region(block.name + "1"), "toggle"); - button.clicked(() -> editor.setDrawBlock(block)); - button.resizeImage(8*4f); - group.add(button); - content.add(button).pad(4f).size(53f, 58f); - - if(i++ % 2 == 1){ - content.row(); - } - } - - group.getButtons().get(2).setChecked(true); - - Table extra = new Table("button"); - extra.labelWrap(() -> editor.getDrawBlock().formalName).width(180f).center(); - table.add(extra).padBottom(-6).growX(); - table.row(); - table.add(pane).growY().fillX(); - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapFilter.java b/core/src/io/anuke/mindustry/mapeditor/MapFilter.java deleted file mode 100644 index bdc1127a90..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapFilter.java +++ /dev/null @@ -1,244 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.ObjectMap; -import com.badlogic.gdx.utils.OrderedMap; - -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; -import io.anuke.mindustry.world.ColorMapper.BlockPair; -import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.types.Floor; -import io.anuke.ucore.graphics.Pixmaps; -import io.anuke.ucore.noise.RidgedPerlin; -import io.anuke.ucore.noise.Simplex; -import io.anuke.ucore.util.Mathf; - -public class MapFilter{ - private ObjectMap prefs = map( - pref("replace", "whether to replace blocks"), - pref("terrain", "generate new terrain"), - pref("circle", "generate terrain in a circle"), - pref("distort", "distort the map image"), - pref("sand", "add patches of sand"), - pref("grass", "add patches of grass"), - pref("stone", "add patches of stone"), - pref("blackstone", "add patches of black stone"), - pref("allgrass", "fill map with grass"), - pref("allsnow", "fill map with snow"), - pref("allsand", "fill map with sand"), - pref("water", "add lakes"), - pref("oil", "add oil lakes"), - pref("lavariver", "add lava rivers"), - pref("slavariver", "ad small lava rivers"), - pref("river", "add rivers"), - pref("iceriver", "add frozen rivers"), - pref("oilriver", "add oil rivers") - ); - - private Simplex sim = new Simplex(); - private RidgedPerlin rid = new RidgedPerlin(1, 10, 20f); - private RidgedPerlin rid2 = new RidgedPerlin(1, 6, 1f); - private RidgedPerlin rid3 = new RidgedPerlin(1, 6, 1f); - - public MapFilter(){ - prefs.get("replace").enabled = true; - prefs.get("terrain").enabled = true; - randomize(); - } - - public void randomize(){ - sim.setSeed(Mathf.random(999999)); - rid.setSeed(Mathf.random(999999)); - rid2.setSeed(Mathf.random(999999)); - rid3.setSeed(Mathf.random(999999)); - } - - public ObjectMap getPrefs(){ - return prefs; - } - - public Pixmap process(Pixmap pixmap){ - if(prefs.get("terrain").enabled){ - for(int x = 0; x < pixmap.getWidth(); x++){ - for(int y = 0; y < pixmap.getHeight(); y++){ - float dist = Vector2.dst((float) x / pixmap.getWidth(), (float) y / pixmap.getHeight(), 0.5f, 0.5f) * 2f; - double noise = sim.octaveNoise2D(6, 0.6, 1 / 180.0, x, y + 9999) / (prefs.get("circle").enabled ? 1.7 : 1f) + dist / 10f; - - if(dist > 0.8){ - noise += 2 * (dist - 0.8); - } - - Block block = noise > 0.6 ? Blocks.stoneblock : Blocks.stone; - - pixmap.drawPixel(x, y, ColorMapper.getColor(block)); - } - } - } - - Pixmap src = Pixmaps.copy(pixmap); - - for(int x = 0; x < pixmap.getWidth(); x++){ - for(int y = 0; y < pixmap.getHeight(); y++){ - int dx = 0, dy = 0; - - if(prefs.get("distort").enabled){ - double intensity = 12; - double scale = 80; - double octaves = 4; - double falloff = 0.6; - double nx = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y) - 0.5f) * intensity; - double ny = (sim.octaveNoise2D(octaves, falloff, 1 / scale, x, y + 99999) - 0.5f) * intensity; - dx = (int) nx; - dy = (int) ny; - } - - int pix = src.getPixel(x + dx, y + dy); - - BlockPair pair = ColorMapper.get(pix); - Block block = pair == null ? null : pair.wall == Blocks.air ? pair.floor : pair.wall; - - if(block == null) - continue; - - boolean floor = block instanceof Floor; - - double noise = sim.octaveNoise2D(4, 0.6, 1 / 170.0, x, y) + sim.octaveNoise2D(1, 1.0, 1 / 5.0, x, y) / 18.0; - double nwater = sim.octaveNoise2D(1, 1.0, 1 / 130.0, x, y); - noise += nwater / 5.0; - - double noil = sim.octaveNoise2D(1, 1.0, 1 / 150.0, x + 9999, y) + sim.octaveNoise2D(1, 1.0, 1 / 2.0, x, y) / 290.0; - - if(!floor || prefs.get("replace").enabled){ - - if(prefs.get("allgrass").enabled){ - block = floor ? Blocks.grass : Blocks.grassblock; - }else if(prefs.get("allsnow").enabled){ - block = floor ? Blocks.snow : Blocks.snowblock; - }else if(prefs.get("allsand").enabled){ - block = floor ? Blocks.sand : Blocks.sandblock; - }else if(prefs.get("replace").enabled){ - block = floor ? Blocks.stone : Blocks.stoneblock; - } - - if(noise > 0.7 && prefs.get("grass").enabled){ - block = floor ? Blocks.grass : Blocks.grassblock; - } - if(noise > 0.7 && prefs.get("blackstone").enabled){ - block = floor ? Blocks.blackstone : Blocks.blackstoneblock; - } - if(noise > 0.7 && prefs.get("sand").enabled){ - block = floor ? Blocks.sand : Blocks.sandblock; - } - if(noise > 0.8 && prefs.get("stone").enabled){ - block = floor ? Blocks.stone : Blocks.stoneblock; - } - } - - if(floor){ - if(nwater > 0.93 && prefs.get("water").enabled){ - block = Blocks.water; - if(nwater > 0.943){ - block = Blocks.deepwater; - } - } - - if(noil > 0.95 && prefs.get("oil").enabled){ - block = Blocks.dirt; - if(noil > 0.955){ - block = Blocks.oil; - } - } - } - - if(floor && prefs.get("lavariver").enabled){ - double lava = rid.getValue(x, y, 1 / 100f); - double t = 0.6; - if(lava > t){ - block = Blocks.lava; - }else if(lava > t - 0.2){ - block = Blocks.blackstone; - } - } - - if(floor && prefs.get("slavariver").enabled){ - double lava = rid.getValue(x, y, 1 / 40f); - double t = 0.7; - if(lava > t){ - block = Blocks.lava; - }else if(lava > t - 0.3){ - block = Blocks.blackstone; - } - } - - if(floor && prefs.get("oilriver").enabled){ - double lava = rid3.getValue(x, y, 1 / 100f); - double t = 0.9; - if(lava > t){ - block = Blocks.oil; - }else if(lava > t - 0.2){ - block = Blocks.dirt; - } - } - - if(floor && prefs.get("river").enabled){ - double riv = rid2.getValue(x, y, 1 / 140f); - double t = 0.4; - - if(riv > t + 0.1){ - block = Blocks.deepwater; - }else if(riv > t){ - block = Blocks.water; - }else if(riv > t - 0.2){ - block = Blocks.grass; - } - } - - if(floor && prefs.get("iceriver").enabled){ - double riv = rid2.getValue(x, y, 1 / 140f); - double t = 0.4; - - if(riv > t + 0.1){ - block = Blocks.ice; - }else if(riv > t){ - block = Blocks.ice; - }else if(riv > t - 0.2){ - block = Blocks.snow; - } - } - - pixmap.drawPixel(x, y, ColorMapper.getColor(block)); - } - } - - src.dispose(); - - return pixmap; - } - - private static OrderedMap map(GenPref...objects){ - OrderedMap prefs = new OrderedMap<>(); - - for(int i = 0; i < objects.length; i ++){ - GenPref pref = (GenPref)objects[i]; - prefs.put(pref.name, pref); - } - return prefs; - } - - private GenPref pref(String name, String desc){ - return new GenPref(name, desc); - } - - class GenPref{ - public final String name; - public final String description; - public boolean enabled; - - GenPref(String name, String description){ - this.name = name; - this.description = description; - } - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java deleted file mode 100644 index ee6535aafe..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java +++ /dev/null @@ -1,105 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.Scaling; - -import static io.anuke.mindustry.Vars.*; -import io.anuke.mindustry.mapeditor.MapFilter.GenPref; -import io.anuke.mindustry.ui.BorderImage; -import io.anuke.mindustry.ui.dialogs.FloatingDialog; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.graphics.Pixmaps; -import io.anuke.ucore.scene.style.TextureRegionDrawable; -import io.anuke.ucore.scene.ui.CheckBox; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.ScrollPane; -import io.anuke.ucore.scene.ui.layout.Stack; -import io.anuke.ucore.scene.ui.layout.Table; - -public class MapGenerateDialog extends FloatingDialog{ - private MapEditor editor; - private Image image; - private boolean loading; - - public MapGenerateDialog(MapEditor editor) { - super("$text.editor.generate"); - this.editor = editor; - - Stack stack = new Stack(); - stack.add(image = new BorderImage()); - - Image loadImage = new Image("icon-loading"); - loadImage.setScaling(Scaling.none); - loadImage.setScale(3f); - loadImage.update(() -> loadImage.setOrigin(Align.center)); - loadImage.setVisible(() -> loading); - Image next = new Image("white"); - next.setScaling(Scaling.fit); - next.setColor(0, 0, 0, 0.6f); - next.setVisible(() -> loading); - - stack.add(next); - stack.add(loadImage); - - content().add(stack).grow(); - image.setScaling(Scaling.fit); - Table preft = new Table(); - preft.left(); - preft.margin(4f).marginRight(25f); - - for(GenPref pref : editor.getFilter().getPrefs().values()){ - CheckBox box = new CheckBox(pref.name); - box.setChecked(pref.enabled); - box.changed(() -> pref.enabled = box.isChecked()); - preft.add(box).pad(4f).left(); - preft.row(); - } - - ScrollPane pane = new ScrollPane(preft, "volume"); - pane.setFadeScrollBars(false); - pane.setScrollingDisabled(true, false); - - content().add(pane).fillY(); - - buttons().defaults().size(170f, 50f).pad(4f); - buttons().addButton("$text.back", this::hide); - buttons().addButton("$text.randomize", () ->{ - editor.getFilter().randomize(); - apply(); - }); - buttons().addButton("$text.update", this::apply); - buttons().addButton("$text.apply", () ->{ - ui.loadfrag.show(); - - Timers.run(3f, () ->{ - Pixmap copy = Pixmaps.copy(editor.pixmap()); - editor.applyFilter(); - ui.editor.getView().push(copy, Pixmaps.copy(editor.pixmap())); - ui.loadfrag.hide(); - ui.editor.resetSaved(); - hide(); - }); - }); - - shown(() ->{ - loading = true; - Timers.run(30f, () -> { - editor.applyFilterPreview(); - image.setDrawable(new TextureRegionDrawable(new TextureRegion(editor.getFilterTexture()))); - loading = false; - }); - }); - } - - private void apply(){ - loading = true; - Timers.run(3f, () -> { - editor.applyFilterPreview(); - loading = false; - }); - - } - -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapLoadDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapLoadDialog.java deleted file mode 100644 index aa71160cfe..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapLoadDialog.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import io.anuke.mindustry.ui.BorderImage; -import io.anuke.mindustry.ui.dialogs.FloatingDialog; -import io.anuke.mindustry.world.Map; -import io.anuke.ucore.function.Consumer; -import io.anuke.ucore.scene.ui.ButtonGroup; -import io.anuke.ucore.scene.ui.ScrollPane; -import io.anuke.ucore.scene.ui.TextButton; -import io.anuke.ucore.scene.ui.layout.Table; - -import static io.anuke.mindustry.Vars.world; - -public class MapLoadDialog extends FloatingDialog{ - private Map selected = world.maps().getMap(0); - - public MapLoadDialog(Consumer loader) { - super("$text.editor.loadmap"); - - shown(this::rebuild); - rebuild(); - - TextButton button = new TextButton("$text.load"); - button.setDisabled(() -> selected == null); - button.clicked(() -> { - if (selected != null) { - loader.accept(selected); - hide(); - } - }); - - buttons().defaults().size(200f, 50f); - buttons().addButton("$text.cancel", this::hide); - buttons().add(button); - } - - public void rebuild(){ - content().clear(); - - selected = world.maps().getMap(0); - - ButtonGroup group = new ButtonGroup<>(); - - int maxcol = 3; - - int i = 0; - - Table table = new Table(); - table.defaults().size(200f, 90f).pad(4f); - table.margin(10f); - - ScrollPane pane = new ScrollPane(table, "horizontal"); - pane.setFadeScrollBars(false); - - for (Map map : world.maps().list()) { - if (!map.visible) continue; - - TextButton button = new TextButton(map.localized(), "toggle"); - button.add(new BorderImage(map.texture, 2f)).size(16 * 4f); - button.getCells().reverse(); - button.clicked(() -> selected = map); - button.getLabelCell().grow().left().padLeft(5f); - group.add(button); - table.add(button); - if (++i % maxcol == 0) table.row(); - } - - content().add("$text.editor.loadmap"); - content().row(); - content().add(pane); - } - -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java deleted file mode 100644 index 6ec83d6cec..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java +++ /dev/null @@ -1,67 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.utils.Align; - -import io.anuke.mindustry.ui.dialogs.FloatingDialog; -import io.anuke.ucore.function.BiConsumer; -import io.anuke.ucore.scene.ui.ButtonGroup; -import io.anuke.ucore.scene.ui.TextButton; -import io.anuke.ucore.scene.ui.layout.Table; - -public class MapResizeDialog extends FloatingDialog{ - int width, height; - - public MapResizeDialog(MapEditor editor, BiConsumer cons){ - super("$text.editor.resizemap"); - shown(() -> { - content().clear(); - Pixmap pix = editor.pixmap(); - width = pix.getWidth(); - height = pix.getHeight(); - - Table table = new Table(); - - for(int d = 0; d < 2; d ++){ - boolean w = d == 0; - int curr = d == 0 ? pix.getWidth() : pix.getHeight(); - int idx = 0; - for(int i = 0; i < MapEditor.validMapSizes.length; i ++) - if(MapEditor.validMapSizes[i] == curr) idx = i; - - table.add(d == 0 ? "$text.width": "$text.height").padRight(8f); - ButtonGroup group = new ButtonGroup<>(); - for(int i = 0; i < MapEditor.validMapSizes.length; i ++){ - int size = MapEditor.validMapSizes[i]; - TextButton button = new TextButton(size + "", "toggle"); - button.clicked(() -> { - if(w) - width = size; - else - height = size; - }); - group.add(button); - if(i == idx) button.setChecked(true); - table.add(button).size(100f, 54f).pad(2f); - } - - table.row(); - } - - content().label(() -> - width + height > 512 ? "$text.editor.resizebig" : "" - ).get().setAlignment(Align.center, Align.center); - content().row(); - content().add(table); - - }); - - buttons().defaults().size(200f, 50f); - buttons().addButton("$text.cancel", this::hide); - buttons().addButton("$text.editor.resize", () -> { - cons.accept(width, height); - hide(); - }); - - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java deleted file mode 100644 index 3090325975..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java +++ /dev/null @@ -1,74 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import io.anuke.mindustry.io.Platform; -import io.anuke.mindustry.ui.dialogs.FloatingDialog; -import io.anuke.mindustry.world.Map; -import io.anuke.ucore.function.Consumer; -import io.anuke.ucore.scene.ui.TextButton; -import io.anuke.ucore.scene.ui.TextField; - -import static io.anuke.mindustry.Vars.*; - -public class MapSaveDialog extends FloatingDialog{ - private TextField field; - private Consumer listener; - - public MapSaveDialog(Consumer cons){ - super("$text.editor.savemap"); - field = new TextField(); - listener = cons; - - Platform.instance.addDialog(field); - - shown(() -> { - content().clear(); - content().label(() ->{ - Map map = world.maps().getMap(field.getText()); - if(map != null){ - if(map.custom){ - return "$text.editor.overwrite"; - }else{ - return "$text.editor.failoverwrite"; - } - } - return ""; - }).colspan(2); - content().row(); - content().add("$text.editor.mapname").padRight(14f); - content().add(field).size(220f, 48f); - }); - - buttons().defaults().size(200f, 50f).pad(2f); - buttons().addButton("$text.cancel", this::hide); - - TextButton button = new TextButton("$text.save"); - button.clicked(() -> { - if(!invalid()){ - cons.accept(field.getText()); - hide(); - } - }); - button.setDisabled(this::invalid); - buttons().add(button); - } - - public void save(){ - if(!invalid()){ - listener.accept(field.getText()); - }else{ - ui.showError("$text.editor.failoverwrite"); - } - } - - public void setFieldText(String text){ - field.setText(text); - } - - private boolean invalid(){ - if(field.getText().isEmpty()){ - return true; - } - Map map = world.maps().getMap(field.getText()); - return map != null && !map.custom; - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java deleted file mode 100644 index 60a13f2815..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/MapView.java +++ /dev/null @@ -1,328 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Colors; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.input.GestureDetector; -import com.badlogic.gdx.input.GestureDetector.GestureListener; -import com.badlogic.gdx.math.Bresenham2; -import com.badlogic.gdx.math.GridPoint2; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack; -import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.ui.GridImage; -import io.anuke.mindustry.world.ColorMapper; -import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Inputs; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Lines; -import io.anuke.ucore.graphics.Pixmaps; -import io.anuke.ucore.scene.Element; -import io.anuke.ucore.scene.event.InputEvent; -import io.anuke.ucore.scene.event.InputListener; -import io.anuke.ucore.scene.event.Touchable; -import io.anuke.ucore.scene.ui.TextField; -import io.anuke.ucore.scene.ui.layout.Unit; -import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Tmp; - -import static io.anuke.mindustry.Vars.ui; - -public class MapView extends Element implements GestureListener{ - private MapEditor editor; - private EditorTool tool = EditorTool.pencil; - private OperationStack stack = new OperationStack(); - private DrawOperation op; - private Pixmap current; - private Bresenham2 br = new Bresenham2(); - private boolean updated = false; - private float offsetx, offsety; - private float zoom = 1f; - private boolean grid = false; - private GridImage image = new GridImage(0, 0); - private Vector2 vec = new Vector2(); - private Rectangle rect = new Rectangle(); - - private boolean drawing; - private int lastx, lasty; - private int startx, starty; - - public void setTool(EditorTool tool){ - this.tool = tool; - } - - public EditorTool getTool() { - return tool; - } - - public void clearStack(){ - stack.clear(); - current = null; - } - - public OperationStack getStack() { - return stack; - } - - public void setGrid(boolean grid) { - this.grid = grid; - } - - public boolean isGrid() { - return grid; - } - - public void push(Pixmap previous, Pixmap add){ - DrawOperation op = new DrawOperation(editor.pixmap()); - op.add(previous, add); - stack.add(op); - this.current = add; - } - - public void undo(){ - if(stack.canUndo()){ - stack.undo(); - editor.updateTexture(); - } - } - - public void redo(){ - if(stack.canRedo()){ - stack.redo(); - editor.updateTexture(); - } - } - - public MapView(MapEditor editor){ - this.editor = editor; - - Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this)); - setTouchable(Touchable.enabled); - - addListener(new InputListener(){ - - @Override - public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { - if(pointer != 0){ - return false; - } - - if(current == null){ - current = Pixmaps.copy(editor.pixmap()); - } - updated = false; - - GridPoint2 p = project(x, y); - lastx = p.x; - lasty = p.y; - startx = p.x; - starty = p.y; - tool.touched(editor, p.x, p.y); - - if(tool.edit){ - updated = true; - ui.editor.resetSaved(); - } - - op = new DrawOperation(editor.pixmap()); - - drawing = true; - return true; - } - - @Override - public void touchUp (InputEvent event, float x, float y, int pointer, int button) { - drawing = false; - - GridPoint2 p = project(x, y); - - if(tool == EditorTool.line){ - ui.editor.resetSaved(); - Array points = br.line(startx, starty, p.x, p.y); - for(GridPoint2 point : points){ - editor.draw(point.x, point.y); - } - updated = true; - } - - if(updated){ - if(op == null) op = new DrawOperation(editor.pixmap()); - Pixmap next = Pixmaps.copy(editor.pixmap()); - op.add(current, next); - current = null; - stack.add(op); - op = null; - } - } - - @Override - public void touchDragged (InputEvent event, float x, float y, int pointer) { - GridPoint2 p = project(x, y); - - if(drawing && tool == EditorTool.pencil){ - ui.editor.resetSaved(); - Array points = br.line(lastx, lasty, p.x, p.y); - for(GridPoint2 point : points){ - editor.draw(point.x, point.y); - } - updated = true; - } - lastx = p.x; - lasty = p.y; - } - }); - } - - @Override - public void act(float delta){ - super.act(delta); - - if(Core.scene.getKeyboardFocus() == null || !(Core.scene.getKeyboardFocus() instanceof TextField) && - !Inputs.keyDown(Keys.CONTROL_LEFT)) { - float ax = Inputs.getAxis("move_x"); - float ay = Inputs.getAxis("move_y"); - offsetx -= ax * 15f / zoom; - offsety -= ay * 15f / zoom; - } - - if(ui.editor.hasPane()) return; - - zoom += Inputs.scroll()/10f * zoom; - clampZoom(); - } - - private void clampZoom(){ - zoom = Mathf.clamp(zoom, 0.2f, 12f); - } - - private GridPoint2 project(float x, float y){ - float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.texture().getWidth(); - y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.texture().getHeight(); - return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y); - } - - private Vector2 unproject(int x, int y){ - float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - float px = ((float)x / editor.texture().getWidth()) * sclwidth + offsetx*zoom - sclwidth/2 + getWidth()/2; - float py = (float)((float)(editor.texture().getHeight() - 1 - y) / editor.texture().getHeight()) * sclheight - + offsety*zoom - sclheight/2 + getHeight()/2; - return vec.set(px, py); - } - - @Override - public void draw(Batch batch, float alpha){ - float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight()); - float size = Math.min(width, height); - float sclwidth = size * zoom; - float sclheight = size * zoom * ratio; - float centerx = x + width/2 + offsetx * zoom; - float centery = y + height/2 + offsety * zoom; - - image.setImageSize(editor.pixmap().getWidth(), editor.pixmap().getHeight()); - - batch.flush(); - boolean pop = ScissorStack.pushScissors(rect.set(x + width/2 - size/2, y + height/2 - size/2, size, size)); - - batch.draw(editor.texture(), centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight); - - if(grid){ - Draw.color(Color.GRAY); - image.setBounds(centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight); - image.draw(batch, alpha); - Draw.color(); - } - - if(tool == EditorTool.line && drawing){ - Vector2 v1 = unproject(startx, starty).add(x, y); - float sx = v1.x, sy = v1.y; - Vector2 v2 = unproject(lastx, lasty).add(x, y); - - Draw.color(Tmp.c1.set(ColorMapper.getColor(editor.getDrawBlock()))); - Lines.stroke(Unit.dp.scl(3f * zoom)); - Lines.line(sx, sy, v2.x, v2.y); - - Lines.poly(sx, sy, 40, editor.getBrushSize() * zoom * 3); - - Lines.poly(v2.x, v2.y, 40, editor.getBrushSize() * zoom * 3); - } - - batch.flush(); - - if(pop) ScissorStack.popScissors(); - - Draw.color(Colors.get("accent")); - Lines.stroke(Unit.dp.scl(3f)); - Lines.rect(x + width/2 - size/2, y + height/2 - size/2, size, size); - Draw.reset(); - } - - private boolean active(){ - return Core.scene.getKeyboardFocus() != null - && Core.scene.getKeyboardFocus().isDescendantOf(ui.editor) - && ui.editor.isShown() && tool == EditorTool.zoom && - Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this; - } - - @Override - public boolean touchDown(float x, float y, int pointer, int button){ - return false; - } - - @Override - public boolean tap(float x, float y, int count, int button){ - return false; - } - - @Override - public boolean longPress(float x, float y){ - return false; - } - - @Override - public boolean fling(float velocityX, float velocityY, int button){ - return false; - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY){ - if(!active()) return false; - offsetx += deltaX / zoom; - offsety -= deltaY / zoom; - return false; - } - - @Override - public boolean panStop(float x, float y, int pointer, int button){ - return false; - } - - @Override - public boolean zoom(float initialDistance, float distance){ - if(!active()) return false; - float nzoom = distance - initialDistance; - zoom += nzoom / 10000f / Unit.dp.scl(1f) * zoom; - clampZoom(); - return false; - } - - @Override - public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2){ - return false; - } - - @Override - public void pinchStop(){ - - } -} diff --git a/core/src/io/anuke/mindustry/mapeditor/OperationStack.java b/core/src/io/anuke/mindustry/mapeditor/OperationStack.java deleted file mode 100755 index 7de9a0c98d..0000000000 --- a/core/src/io/anuke/mindustry/mapeditor/OperationStack.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.anuke.mindustry.mapeditor; - -import com.badlogic.gdx.utils.Array; - -public class OperationStack{ - private final static int maxSize = 10; - private Array stack = new Array<>(); - private int index = 0; - - public OperationStack(){ - - } - - public void clear(){ - for(DrawOperation op : stack){ - op.dispose(); - } - stack.clear(); - index = 0; - } - - public void add(DrawOperation action){ - stack.truncate(stack.size + index); - index = 0; - stack.add(action); - - if(stack.size > maxSize){ - stack.get(0).disposeFrom(); - stack.removeIndex(0); - } - } - - public boolean canUndo(){ - return !(stack.size - 1 + index < 0); - } - - public boolean canRedo(){ - return !(index > -1 || stack.size + index < 0); - } - - public void undo(){ - if(!canUndo()) return; - - stack.get(stack.size - 1 + index).undo(); - index --; - } - - public void redo(){ - if(!canRedo()) return; - - index ++; - stack.get(stack.size - 1 + index).redo(); - - } -} diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 8196fbc6ab..bd27df11eb 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -1,20 +1,19 @@ package io.anuke.mindustry.net; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.utils.ByteArray; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.game.GameMode; +import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.Version; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; -import io.anuke.mindustry.world.*; +import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.BlockPart; -import io.anuke.mindustry.world.blocks.types.Rock; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.util.Bits; import java.io.*; import java.nio.ByteBuffer; @@ -23,86 +22,6 @@ import static io.anuke.mindustry.Vars.*; public class NetworkIO { - public static void writeMap(Map map, OutputStream os){ - try(DataOutputStream stream = new DataOutputStream(os)){ - stream.writeUTF(map.name); - stream.writeBoolean(map.oreGen); - - stream.writeShort(map.getWidth()); - stream.writeShort(map.getHeight()); - - int width = map.getWidth(); - int cap = map.getWidth() * map.getHeight(); - int pos = 0; - - while(pos < cap){ - int color = map.pixmap.getPixel(pos % width, pos / width); - byte id = ColorMapper.getColorID(color); - - int length = 1; - while(true){ - if(pos >= cap || length > 254){ - break; - } - - pos ++; - - int next = map.pixmap.getPixel(pos % width, pos / width); - if(next != color){ - pos --; - break; - }else{ - length ++; - } - } - - if(id == -1) id = 2; - stream.writeByte((byte)(length > 127 ? length - 256 : length)); - stream.writeByte(id); - - pos ++; - } - }catch (IOException e){ - throw new RuntimeException(e); - } - } - - public static Map loadMap(InputStream is){ - try(DataInputStream stream = new DataInputStream(is)){ - String name = stream.readUTF(); - boolean ores = stream.readBoolean(); - - short width = stream.readShort(); - short height = stream.readShort(); - Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888); - - int pos = 0; - while(stream.available() > 0){ - int length = stream.readByte(); - byte id = stream.readByte(); - if(length < 0) length += 256; - int color = ColorMapper.getColorByID(id); - - for(int p = 0; p < length; p ++){ - pixmap.drawPixel(pos % width, pos / width,color); - pos ++; - } - } - - Map map = new Map(); - map.name = name; - map.oreGen = ores; - map.custom = true; - map.pixmap = pixmap; - map.visible = false; - map.id = -1; - - return map; - }catch (IOException e){ - throw new RuntimeException(e); - } - } - public static void writeWorld(Player player, ByteArray upgrades, OutputStream os){ try(DataOutputStream stream = new DataOutputStream(os)){ @@ -112,7 +31,7 @@ public class NetworkIO { //--GENERAL STATE-- stream.writeByte(state.mode.ordinal()); //gamemode - stream.writeByte(world.getMap().custom ? -1 : world.getMap().id); //map ID + stream.writeUTF(world.getMap().name); //map ID stream.writeInt(state.wave); //wave stream.writeFloat(state.wavetime); //wave countdown @@ -136,87 +55,33 @@ public class NetworkIO { //--MAP DATA-- - //seed - stream.writeInt(world.getSeed()); - - int totalblocks = 0; - int totalrocks = 0; + //map size + stream.writeShort(world.width()); + stream.writeShort(world.height()); for(int x = 0; x < world.width(); x ++){ for(int y = 0; y < world.height(); y ++){ Tile tile = world.tile(x, y); - if(tile.breakable()){ - if(tile.block() instanceof Rock){ - totalrocks ++; - }else{ - totalblocks ++; - } + //TODO will break if block number gets over BYTE_MAX + stream.writeByte(tile.floor().id); //floor ID + stream.writeByte(tile.block().id); //block ID + + if(tile.block() instanceof BlockPart){ + stream.writeByte(tile.link); } - } - } - //amount of rocks - stream.writeInt(totalrocks); + if(tile.entity != null){ + stream.writeByte(Bits.packByte((byte)tile.getTeam().ordinal(), tile.getRotation())); + stream.writeShort((short)tile.entity.health); //health - //write all rocks - for(int x = 0; x < world.width(); x ++) { - for (int y = 0; y < world.height(); y++) { - Tile tile = world.tile(x, y); + if(tile.entity.inventory != null) tile.entity.inventory.write(stream); + if(tile.entity.power != null) tile.entity.power.write(stream); + if(tile.entity.liquid != null) tile.entity.liquid.write(stream); - if (tile.block() instanceof Rock) { - stream.writeInt(tile.packedPosition()); + tile.entity.write(stream); } - } - } - //tile amount - stream.writeInt(totalblocks); - - for(int x = 0; x < world.width(); x ++){ - for(int y = 0; y < world.height(); y ++){ - Tile tile = world.tile(x, y); - - if(tile.breakable() && !(tile.block() instanceof Rock)){ - - stream.writeInt(x + y*world.width()); //tile pos - //TODO will break if block number gets over BYTE_MAX - stream.writeByte(tile.block().id); //block ID - - if(tile.block() instanceof BlockPart){ - stream.writeByte(tile.link); - } - - if(tile.entity != null){ - stream.writeByte(tile.getRotation()); - stream.writeByte(tile.getDump()); - stream.writeByte(tile.getExtra()); - stream.writeShort((short)tile.entity.health); //health - - if(tile.entity.inventory != null) tile.entity.inventory.write(stream); - if(tile.entity.power != null) tile.entity.power.write(stream); - if(tile.entity.liquid != null) tile.entity.liquid.write(stream); - - //timer data - - //amount of active timers - byte times = 0; - - for(; times < tile.entity.timer.getTimes().length; times ++){ - if(tile.entity.timer.getTimes()[times] <= 1){ - break; - } - } - - stream.writeByte(times); - - for(int i = 0; i < times; i ++){ - stream.writeFloat(tile.entity.timer.getTimes()[i]); - } - - tile.entity.write(stream); - } - } } } @@ -228,6 +93,8 @@ public class NetworkIO { /**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/ public static void loadWorld(InputStream is){ + //TODO !! use map name as the network map in Maps, so getMap() isn't null. + try(DataInputStream stream = new DataInputStream(is)){ float timerTime = stream.readFloat(); long timestamp = stream.readLong(); @@ -237,7 +104,7 @@ public class NetworkIO { //general state byte mode = stream.readByte(); - byte mapid = stream.readByte(); + String map = stream.readUTF(); int wave = stream.readInt(); float wavetime = stream.readFloat(); @@ -266,7 +133,7 @@ public class NetworkIO { byte weapons = stream.readByte(); for(int i = 0; i < weapons; i ++){ - control.upgrades().getWeapons().add((Weapon) Upgrade.getByID(stream.readByte())); + control.upgrades().getWeapons().add(Upgrade.getByID(stream.readByte())); } player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().peek(); @@ -278,68 +145,44 @@ public class NetworkIO { player.add(); //map + int width = stream.readShort(); + int height = stream.readShort(); - int seed = stream.readInt(); - - world.loadMap(world.maps().getMap(mapid), seed); - renderer.clearTiles(); - - player.set(world.getSpawnX(), world.getSpawnY()); + Tile[][] tiles = world.createTiles(width, height); for(int x = 0; x < world.width(); x ++){ for(int y = 0; y < world.height(); y ++){ - Tile tile = world.tile(x, y); + byte floorid = stream.readByte(); + byte blockid = stream.readByte(); - //remove breakables like rocks - if(tile.breakable()){ - world.tile(x, y).setBlock(Blocks.air); - } - } - } + Tile tile = new Tile(x, y, floorid, blockid); - int rocks = stream.readInt(); - - for(int i = 0; i < rocks; i ++){ - int pos = stream.readInt(); - Tile tile = world.tile(pos % world.width(), pos / world.width()); - Block result = WorldGenerator.rocks.get(tile.floor()); - if(result != null) tile.setBlock(result); - } - - int tiles = stream.readInt(); - - for(int i = 0; i < tiles; i ++){ - int pos = stream.readInt(); - byte blockid = stream.readByte(); - - Tile tile = world.tile(pos % world.width(), pos / world.width()); - tile.setBlock(Block.getByID(blockid)); - - if(tile.block() == Blocks.blockpart){ - tile.link = stream.readByte(); - } - - if(tile.entity != null){ - tile.setRotation(stream.readByte()); - tile.setDump(stream.readByte()); - tile.setExtra(stream.readByte()); - short health = stream.readShort(); - - tile.entity.health = health; - - if(tile.entity.inventory != null) tile.entity.inventory.read(stream); - if(tile.entity.power != null) tile.entity.power.read(stream); - if(tile.entity.liquid != null) tile.entity.liquid.read(stream); - - byte timers = stream.readByte(); - for(int time = 0; time < timers; time ++){ - tile.entity.timer.getTimes()[time] = stream.readFloat(); + if(tile.block() == Blocks.blockpart){ + tile.link = stream.readByte(); } - tile.entity.read(stream); + if(tile.entity != null) { + byte tr = stream.readByte(); + short health = stream.readShort(); + + tile.setTeam(Team.values()[Bits.getLeftByte(tr)]); + tile.setRotation(Bits.getRightByte(tr)); + + tile.entity.health = health; + + if (tile.entity.inventory != null) tile.entity.inventory.read(stream); + if (tile.entity.power != null) tile.entity.power.read(stream); + if (tile.entity.liquid != null) tile.entity.liquid.read(stream); + + tile.entity.read(stream); + } + + tiles[x][y] = tile; } } + player.set(world.getSpawnX(), world.getSpawnY()); + }catch (IOException e){ throw new RuntimeException(e); } diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 4dad5587e3..467ad3b6b8 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -14,6 +14,7 @@ import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.Block; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; +import io.anuke.ucore.util.IOUtils; import java.nio.ByteBuffer; @@ -64,8 +65,7 @@ public class Packets { @Override public void write(ByteBuffer buffer) { buffer.putInt(Version.build); - buffer.put((byte)name.getBytes().length); - buffer.put(name.getBytes()); + IOUtils.writeString(buffer, name); buffer.put(android ? (byte)1 : 0); buffer.putInt(color); buffer.put(uuid); @@ -74,10 +74,7 @@ public class Packets { @Override public void read(ByteBuffer buffer) { version = buffer.getInt(); - byte length = buffer.get(); - byte[] bytes = new byte[length]; - buffer.get(bytes); - name = new String(bytes); + name = IOUtils.readString(buffer); android = buffer.get() == 1; color = buffer.getInt(); uuid = new byte[8]; @@ -320,8 +317,7 @@ public class Packets { }else{ buffer.putShort((short)-1); } - buffer.putShort((short)text.getBytes().length); - buffer.put(text.getBytes()); + IOUtils.writeString(buffer, text); buffer.putInt(id); } @@ -333,12 +329,9 @@ public class Packets { buffer.get(n); name = new String(n); } - short tlength = buffer.getShort(); - byte[] t = new byte[tlength]; - buffer.get(t); + text = IOUtils.readString(buffer); id = buffer.getInt(); - text = new String(t); } } @@ -487,16 +480,12 @@ public class Packets { @Override public void write(ByteBuffer buffer) { - buffer.putShort((short)message.getBytes().length); - buffer.put(message.getBytes()); + IOUtils.writeString(buffer, message); } @Override public void read(ByteBuffer buffer) { - short length = buffer.getShort(); - byte[] bytes = new byte[length]; - buffer.get(bytes); - message = new String(bytes); + message = IOUtils.readString(buffer); } } diff --git a/core/src/io/anuke/mindustry/resource/Weapon.java b/core/src/io/anuke/mindustry/resource/Weapon.java index 1359cd6ede..6b9cefcbbb 100644 --- a/core/src/io/anuke/mindustry/resource/Weapon.java +++ b/core/src/io/anuke/mindustry/resource/Weapon.java @@ -4,12 +4,12 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; -import io.anuke.ucore.entities.Entity; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Translator; @@ -125,7 +125,7 @@ public class Weapon extends Upgrade{ } } - void bullet(Entity owner, float x, float y, float angle){ + void bullet(Unit owner, float x, float y, float angle){ tr.trns(angle, 3f); new Bullet(type, owner, x + tr.x, y + tr.y, angle).add(); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java index 612945183e..45b040ef18 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LevelDialog.java @@ -1,15 +1,13 @@ package io.anuke.mindustry.ui.dialogs; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.world.Map; +import io.anuke.mindustry.io.Map; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.scene.event.ClickListener; -import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.layout.Stack; @@ -21,7 +19,6 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class LevelDialog extends FloatingDialog{ - private Map selectedMap = world.maps().getMap(0); private ScrollPane pane; public LevelDialog(){ @@ -88,10 +85,8 @@ public class LevelDialog extends FloatingDialog{ content().row(); int i = 0; - for(Map map : world.maps().list()){ - - if(!map.visible && !debug) continue; - + for(Map map : world.maps().all()){ + if(i % maxwidth == 0){ maps.row(); } @@ -115,40 +110,16 @@ public class LevelDialog extends FloatingDialog{ Stack stack = new Stack(); Image back = new Image("white"); - back.setColor(map.backgroundColor); + back.setColor(Color.valueOf("646464")); ImageButton image = new ImageButton(new TextureRegion(map.texture), "togglemap"); image.row(); image.add(inset).width(images+6); - TextButton[] delete = new TextButton[1]; - if(map.custom){ - image.row(); - delete[0] = image.addButton("Delete", () -> { - Timers.run(1f, () -> { - ui.showConfirm("$text.level.delete.title", Bundles.format("text.level.delete", Bundles.get("map."+map.name+".name", map.name)), () -> { - world.maps().removeMap(map); - reload(); - Core.scene.setScrollFocus(pane); - }); - }); - }).width(images+16).padBottom(-10f).grow().get(); - } + //TODO custom map delete button - Vector2 hit = new Vector2(); - - image.addListener(new ClickListener(){ - public void clicked(InputEvent event, float x, float y){ - image.localToStageCoordinates(hit.set(x, y)); - if(delete[0] != null && (delete[0].getClickListener().isOver() || delete[0].getClickListener().isPressed() - || (Core.scene.hit(hit.x, hit.y, true) != null && - Core.scene.hit(hit.x, hit.y, true).isDescendantOf(delete[0])))){ - return; - } - - selectedMap = map; - hide(); - control.playMap(selectedMap); - } + image.clicked(() -> { + hide(); + control.playMap(map); }); image.getImageCell().size(images); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index a7e7b653cc..2cc81f41e5 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -100,7 +100,7 @@ public class LoadDialog extends FloatingDialog{ button.defaults().padBottom(3); button.row(); - button.add(Bundles.format("text.save.map", color+slot.getMap().localized())); + button.add(Bundles.format("text.save.map", color+slot.getMap().meta.name())); button.row(); button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode()); button.row(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 2aeda7122e..d588c7c089 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -50,7 +50,7 @@ public class PausedDialog extends FloatingDialog{ content().row(); content().addButton("$text.savegame", () -> { save.show(); - }).disabled(b -> world.getMap().id == -1); + }); content().row(); content().addButton("$text.loadgame", () -> { @@ -93,7 +93,6 @@ public class PausedDialog extends FloatingDialog{ imagebutton sa = new imagebutton("icon-save", isize, save::show); sa.text("$text.save").padTop(4f); - sa.cell.disabled(b -> world.getMap().id == -1); content().row(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java index 477e927b3a..6b3461bd46 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java @@ -121,8 +121,6 @@ public class DebugFragment implements Fragment { "players: " + playerGroup.size(), "tiles: " + tileGroup.size(), "time: " + Timers.time(), - world.getCore() != null && world.getCore().entity != null ? "core.health: " + world.getCore().entity.health : "", - "core: " + world.getCore(), "state.gameover: " + state.gameOver, "state: " + state.getState(), !Net.server() ? clientDebug.getOut() : serverDebug.getOut() diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index a4133b9122..3bb831dd07 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -62,7 +62,7 @@ public class MenuFragment implements Fragment{ new imagebutton("icon-play-2", isize, ui.levels::show).text("$text.play").padTop(4f); - new imagebutton("icon-tutorial", isize, () -> control.playMap(world.maps().getMap("tutorial"))).text("$text.tutorial").padTop(4f); + new imagebutton("icon-tutorial", isize, () -> control.playMap(world.maps().getByName("tutorial"))).text("$text.tutorial").padTop(4f); new imagebutton("icon-load", isize, ui.load::show).text("$text.load").padTop(4f); @@ -120,7 +120,7 @@ public class MenuFragment implements Fragment{ } })); dialog.content().add(new MenuButton("icon-tutorial", "$text.tutorial", ()-> { - control.playMap(world.maps().getMap("tutorial")); + control.playMap(world.maps().getByName("tutorial")); dialog.hide(); })); diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index 617c43bb95..b14b853932 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -6,9 +6,7 @@ import com.badlogic.gdx.utils.IntIntMap; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntMap.Entry; import com.badlogic.gdx.utils.ObjectIntMap; - import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.SpecialBlocks; public class ColorMapper{ /**maps color IDs to their actual RGBA8888 colors*/ @@ -19,8 +17,6 @@ public class ColorMapper{ private static ObjectIntMap reverseColors = new ObjectIntMap<>(); private static Array pairs = new Array<>(); private static IntMap colors = map( - "ff0000", pair(Blocks.dirt, SpecialBlocks.enemySpawn), - "00ff00", pair(Blocks.stone, SpecialBlocks.playerSpawn), "323232", pair(Blocks.stone), "646464", pair(Blocks.stone, Blocks.stoneblock), "50965a", pair(Blocks.grass), diff --git a/core/src/io/anuke/mindustry/world/Map.java b/core/src/io/anuke/mindustry/world/Map.java deleted file mode 100644 index e11d07fe94..0000000000 --- a/core/src/io/anuke/mindustry/world/Map.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.anuke.mindustry.world; - -public class Map{ - public String name; - public String author; - public String description; - public boolean visible = true; - public boolean custom = false; - public boolean oreGen = true; -} diff --git a/core/src/io/anuke/mindustry/world/Placement.java b/core/src/io/anuke/mindustry/world/Placement.java index bf44a50613..5aae07397e 100644 --- a/core/src/io/anuke/mindustry/world/Placement.java +++ b/core/src/io/anuke/mindustry/world/Placement.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Units; -import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.resource.ItemStack; @@ -93,13 +92,6 @@ public class Placement { } public static boolean validPlace(Team team, int x, int y, Block type){ - for(int i = 0; i < world.getSpawns().size; i ++){ - SpawnPoint spawn = world.getSpawns().get(i); - if(Vector2.dst(x * tilesize, y * tilesize, spawn.start.worldx(), spawn.start.worldy()) < enemyspawnspace){ - return false; - } - } - Recipe recipe = Recipes.getByResult(type); if(recipe == null || !state.inventory.hasItems(recipe.requirements)){ @@ -157,8 +149,9 @@ public class Placement { } } + //TODO make this work! public static boolean isSpawnPoint(Tile tile){ - return tile != null && tile.x == world.getCore().x && tile.y == world.getCore().y - 2; + return false; } public static boolean validBreak(Team team, int x, int y){ diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index f2f779f518..57700de5c8 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -37,24 +37,25 @@ public class Tile{ this.x = (short)x; this.y = (short)y; } - - public Tile(int x, int y, Block floor){ + + public Tile(int x, int y, byte floor, byte wall){ this(x, y); - iSetFloor(floor); + this.floor = floor; + this.wall = wall; + } + + public Tile(int x, int y, byte floor, byte wall, byte rotation, byte team){ + this(x, y); + this.floor = floor; + this.wall = wall; + this.rotation = rotation; + this.team = team; } public int packedPosition(){ return x + y * world.width(); } - private void iSetFloor(Block floor){ - this.floor = (byte)floor.id; - } - - private void iSetBlock(Block wall){ - this.wall = (byte)wall.id; - } - public byte getWallID(){ return wall; } @@ -130,23 +131,23 @@ public class Tile{ public void setBlock(Block type, int rotation){ synchronized (tileSetLock) { if(rotation < 0) rotation = (-rotation + 2); - iSetBlock(type); - setRotation((byte) (rotation % 4)); + this.wall = (byte)type.id; this.link = 0; + setRotation((byte) (rotation % 4)); changed(); } } public void setBlock(Block type){ synchronized (tileSetLock) { - iSetBlock(type); + this.wall = (byte)type.id; this.link = 0; changed(); } } public void setFloor(Block type){ - iSetFloor(type); + this.floor = (byte)type.id; } public void setRotation(byte rotation){ diff --git a/core/src/io/anuke/mindustry/world/WorldGenerator.java b/core/src/io/anuke/mindustry/world/WorldGenerator.java index f3a33c98fe..488679416a 100644 --- a/core/src/io/anuke/mindustry/world/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/WorldGenerator.java @@ -1,19 +1,14 @@ package io.anuke.mindustry.world; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; -import io.anuke.mindustry.game.SpawnPoint; -import io.anuke.mindustry.world.ColorMapper.BlockPair; +import io.anuke.mindustry.io.MapTileData; +import io.anuke.mindustry.io.MapTileData.TileData; import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.SpecialBlocks; -import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.noise.Noise; -import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; + public class WorldGenerator { public static final ObjectMap rocks = new ObjectMap(){{ put(Blocks.stone, Blocks.rock); @@ -22,67 +17,21 @@ public class WorldGenerator { put(Blocks.blackstone, Blocks.blackrock); }}; - /**Returns the core (starting) block. Should fill spawns with the correct spawnpoints.*/ - public static void generate(Tile[][] tiles, Map map){ + /**Should fill spawns with the correct spawnpoints.*/ + public static void generate(Tile[][] tiles, MapTileData data){ Noise.setSeed(world.getSeed()); - for(int x = 0; x < pixmap.getWidth(); x ++){ - for(int y = 0; y < pixmap.getHeight(); y ++){ - Block floor = Blocks.stone; - Block block = Blocks.air; - - int color = pixmap.getPixel(x, pixmap.getHeight()-1-y); - BlockPair pair = ColorMapper.get(color); - - if(pair != null){ - block = pair.wall; - floor = pair.floor; - } - - if(block == SpecialBlocks.playerSpawn){ - block = Blocks.air; - core = world.tile(x, y); - }else if(block == SpecialBlocks.enemySpawn){ - block = Blocks.air; - spawns.add(new SpawnPoint(tiles[x][y])); - } - - if(block == Blocks.air && Mathf.chance(0.025) && rocks.containsKey(floor)){ - block = rocks.get(floor); - } - - if(world.getMap().oreGen && (floor == Blocks.stone || floor == Blocks.grass || floor == Blocks.blackstone || - floor == Blocks.snow || floor == Blocks.sand)){ - if(Noise.nnoise(x, y, 8, 1) > 0.21){ - floor = Blocks.iron; - } - - if(Noise.nnoise(x, y, 6, 1) > 0.237){ - floor = Blocks.coal; - } - - if(Noise.nnoise(x + 9999, y + 9999, 8, 1) > 0.27){ - floor = Blocks.titanium; - } - - if(Noise.nnoise(x + 99999, y + 99999, 7, 1) > 0.259){ - floor = Blocks.uranium; - } - } - - if(color == Hue.rgb(Color.PURPLE)){ - //TODO place unit here - //if(!Vars.android) new BaseUnit(UnitTypes.target).set(x * tilesize, y * tilesize).add(); - floor = Blocks.stone; - } - - tiles[x][y].setBlock(block, 0); - tiles[x][y].setFloor(floor); + for(int x = 0; x < data.width(); x ++){ + for(int y = 0; y < data.height(); y ++){ + TileData tile = data.read(); + tiles[x][y] = new Tile(x, y, tile.floor, tile.wall, tile.rotation, tile.team); + + //TODO ores, plants, extra decoration? } } - for(int x = 0; x < pixmap.getWidth(); x ++){ - for(int y = 0; y < pixmap.getHeight(); y ++) { + for(int x = 0; x < data.width(); x ++){ + for(int y = 0; y < data.height(); y ++) { tiles[x][y].updateOcclusion(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java index ca45d44849..8e05184f2d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java @@ -229,7 +229,7 @@ public class Turret extends Block{ } protected void bullet(Tile tile, float angle){ - new Bullet(bullet, tile.entity, tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add(); + new Bullet(bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle).add(); } public static class TurretEntity extends TileEntity{ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/types/storage/CoreBlock.java index 67deee20a7..84acd2992c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/storage/CoreBlock.java @@ -6,6 +6,7 @@ import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.debug; import static io.anuke.mindustry.Vars.state; +import static io.anuke.mindustry.Vars.world; public class CoreBlock extends StorageBlock { protected int capacity = 1000; @@ -25,6 +26,12 @@ public class CoreBlock extends StorageBlock { return debug ? 0 : amount; } + public void onDestroyed(Tile tile){ + //TODO more dramatic effects + super.onDestroyed(tile); + world.getAllyCores().removeValue(tile, true); + } + @Override public void handleItem(Item item, Tile tile, Tile source){ if(Net.server() || !Net.active()) state.inventory.addItem(item, 1);