From 02ab945ab869618fb088f29b69f81f9f578483ef Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 14 Apr 2018 21:57:10 -0400 Subject: [PATCH 01/18] Made junction ignore clogs --- core/assets/version.properties | 4 ++-- .../world/blocks/types/distribution/Junction.java | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/assets/version.properties b/core/assets/version.properties index ad7d533aa9..68dd48f5aa 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sat Apr 14 20:43:56 EDT 2018 +#Sat Apr 14 21:55:24 EDT 2018 version=release -androidBuildCode=513 +androidBuildCode=514 name=Mindustry code=3.5 build=custom build diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Junction.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Junction.java index bfaa422cd0..a15f402fe7 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Junction.java @@ -32,6 +32,7 @@ public class Junction extends Block{ for(int i = 0; i < 2; i ++){ Buffer buffer = (i == 0 ? entity.bx : entity.by); + if(buffer.index > 0){ if(buffer.index > buffer.items.length) buffer.index = buffer.items.length; long l = buffer.items[0]; @@ -45,7 +46,13 @@ public class Junction extends Block{ int direction = Bits.getRightShort(val); Tile dest = tile.getNearby(direction); - if(dest == null || !dest.block().acceptItem(item, dest, tile)) continue; + if(dest == null || !dest.block().acceptItem(item, dest, tile)){ + if(buffer.index > 1){ + System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); + buffer.index --; + } + continue; + } dest.block().handleItem(item, dest, tile); System.arraycopy(buffer.items, 1, buffer.items, 0, buffer.index - 1); From c17b34c70d484bd28601ecc95c79decd43774885 Mon Sep 17 00:00:00 2001 From: Commodore64x Date: Sun, 15 Apr 2018 19:40:22 +1000 Subject: [PATCH 02/18] Added Placement Preview --- core/assets/bundles/bundle.properties | 1 + .../mindustry/graphics/BlockRenderer.java | 554 +++++++------ .../io/anuke/mindustry/input/PlaceMode.java | 747 +++++++++--------- .../ui/dialogs/SettingsMenuDialog.java | 1 + 4 files changed, 677 insertions(+), 626 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 63a3e099d4..72a00fc860 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -270,6 +270,7 @@ setting.multithread.name=Multithreading setting.fps.name=Show FPS setting.vsync.name=VSync setting.lasers.name=Show Power Lasers +setting.previewopacity.name = Placing Preview Opacity setting.healthbars.name=Show Entity Health bars setting.pixelate.name=Pixelate Screen setting.musicvol.name=Music Volume diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index e53ffacd1b..84e3cf8b17 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -12,12 +12,16 @@ import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.StaticBlock; +import io.anuke.mindustry.world.blocks.types.defense.Turret; +import io.anuke.mindustry.world.blocks.types.production.Drill; +import io.anuke.mindustry.world.blocks.types.production.Pump; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.graphics.CacheBatch; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.core.*; import java.util.Arrays; @@ -25,259 +29,297 @@ import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.core.Core.camera; public class BlockRenderer{ - private final static int chunksize = 32; - private final static int initialRequests = 32*32; - - private int[][][] cache; - private CacheBatch cbatch; - - private Array requests = new Array(initialRequests); - private int requestidx = 0; - private int iterateidx = 0; - - public BlockRenderer(){ - for(int i = 0; i < requests.size; i ++){ - requests.set(i, new BlockRequest()); - } - } - - private class BlockRequest implements Comparable{ - Tile tile; - Layer layer; - - @Override - public int compareTo(BlockRequest other){ - return layer.compareTo(other.layer); - } - - @Override - public String toString(){ - return tile.block().name + ":" + layer.toString(); - } - } - - /**Process all blocks to draw, simultaneously drawing block shadows and static blocks.*/ - public void processBlocks(){ - requestidx = 0; - - int crangex = (int) (camera.viewportWidth / (chunksize * tilesize)) + 1; - int crangey = (int) (camera.viewportHeight / (chunksize * tilesize)) + 1; - - int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2)+2; - int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2)+2; - - int expandr = 3; - - Graphics.surface(renderer.shadowSurface); - - for(int x = -rangex - expandr; x <= rangex + expandr; x++){ - for(int y = -rangey - expandr; y <= rangey + expandr; y++){ - int worldx = Mathf.scl(camera.position.x, tilesize) + x; - int worldy = Mathf.scl(camera.position.y, tilesize) + y; - boolean expanded = (x < -rangex || x > rangex || y < -rangey || y > rangey); - - Tile tile = world.tile(worldx, worldy); - - if(tile != null){ - Block block = tile.block(); - - if(!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)){ - block.drawShadow(tile); - } - - if(!(block instanceof StaticBlock)){ - if(block == Blocks.air){ - if(!state.is(State.paused)) tile.floor().update(tile); - }else{ - - if(!expanded){ - addRequest(tile, Layer.block); - } - - if(block.expanded || !expanded){ - if(block.layer != null && block.isLayer(tile)){ - addRequest(tile, block.layer); - } - - if(block.layer2 != null && block.isLayer2(tile)){ - addRequest(tile, block.layer2); - } - } - } - } - } - } - } - - Draw.color(0, 0, 0, 0.15f); - Graphics.flushSurface(); - Draw.color(); - - Graphics.end(); - drawCache(1, crangex, crangey); - Graphics.begin(); - - Arrays.sort(requests.items, 0, requestidx); - iterateidx = 0; - } - - public int getRequests(){ - return requestidx; - } - - public void drawBlocks(boolean top){ - Layer stopAt = top ? Layer.laser : Layer.overlay; - - for(; iterateidx < requestidx; iterateidx ++){ - - if(iterateidx < requests.size - 1 && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ - break; - } - - BlockRequest req = requests.get(iterateidx); - Block block = req.tile.block(); - - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } - } - } - - private void addRequest(Tile tile, Layer layer){ - if(requestidx >= requests.size){ - requests.add(new BlockRequest()); - } - BlockRequest r = requests.get(requestidx); - if(r == null){ - requests.set(requestidx, r = new BlockRequest()); - } - r.tile = tile; - r.layer = layer; - requestidx ++; - } - - public void drawFloor(){ - int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize; - - //render the entire map - if(cache == null || cache.length != chunksx || cache[0].length != chunksy){ - cache = new int[chunksx][chunksy][2]; - - for(int x = 0; x < chunksx; x++){ - for(int y = 0; y < chunksy; y++){ - cacheChunk(x, y, true); - cacheChunk(x, y, false); - } - } - } - - OrthographicCamera camera = Core.camera; - - if(Graphics.drawing()) Graphics.end(); - - int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; - int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; - - drawCache(0, crangex, crangey); - - Graphics.begin(); - - Draw.reset(); - - if(showPaths && debug){ - drawPaths(); - } - - if(debug && debugChunks){ - Draw.color(Color.YELLOW); - Lines.stroke(1f); - for(int x = -crangex; x <= crangex; x++){ - for(int y = -crangey; y <= crangey; y++){ - int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; - int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; - - if(!Mathf.inBounds(worldx, worldy, cache)) - continue; - Lines.rect(worldx * chunksize * tilesize, worldy * chunksize * tilesize, chunksize * tilesize, chunksize * tilesize); - } - } - 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(int layer, int crangex, int crangey){ - Gdx.gl.glEnable(GL20.GL_BLEND); - - cbatch.setProjectionMatrix(Core.camera.combined); - cbatch.beginDraw(); - for(int x = -crangex; x <= crangex; x++){ - for(int y = -crangey; y <= crangey; y++){ - int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; - int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; - - if(!Mathf.inBounds(worldx, worldy, cache)) - continue; - - cbatch.drawCache(cache[worldx][worldy][layer]); - } - } - - cbatch.endDraw(); - } - - void cacheChunk(int cx, int cy, boolean floor){ - if(cbatch == null){ - createBatch(); - } - - cbatch.begin(); - Graphics.useBatch(cbatch); - - for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ - for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ - Tile tile = world.tile(tilex, tiley); - if(tile == null) continue; - if(floor){ - if(!(tile.block() instanceof StaticBlock)){ - tile.floor().draw(tile); - } - }else if(tile.block() instanceof StaticBlock){ - tile.block().draw(tile); - } - } - } - Graphics.popBatch(); - cbatch.end(); - cache[cx][cy][floor ? 0 : 1] = cbatch.getLastCache(); - } - - public void clearTiles(){ - cache = null; - createBatch(); - } - - private void createBatch(){ - if(cbatch != null) - cbatch.dispose(); - cbatch = new CacheBatch(world.width() * world.height() * 4); - } -} + private final static int chunksize = 32; + private final static int initialRequests = 32*32; + + private int[][][] cache; + private CacheBatch cbatch; + + private Array requests = new Array(initialRequests); + private int requestidx = 0; + private int iterateidx = 0; + + public BlockRenderer(){ + for(int i = 0; i < requests.size; i ++){ + requests.set(i, new BlockRequest()); + } + } + + private class BlockRequest implements Comparable{ + Tile tile; + Layer layer; + + @Override + public int compareTo(BlockRequest other){ + return layer.compareTo(other.layer); + } + + @Override + public String toString(){ + return tile.block().name + ":" + layer.toString(); + } + } + + /**Process all blocks to draw, simultaneously drawing block shadows and static blocks.*/ + public void processBlocks(){ + requestidx = 0; + + int crangex = (int) (camera.viewportWidth / (chunksize * tilesize)) + 1; + int crangey = (int) (camera.viewportHeight / (chunksize * tilesize)) + 1; + + int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2)+2; + int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2)+2; + + int expandr = 3; + + Graphics.surface(renderer.shadowSurface); + + for(int x = -rangex - expandr; x <= rangex + expandr; x++){ + for(int y = -rangey - expandr; y <= rangey + expandr; y++){ + int worldx = Mathf.scl(camera.position.x, tilesize) + x; + int worldy = Mathf.scl(camera.position.y, tilesize) + y; + boolean expanded = (x < -rangex || x > rangex || y < -rangey || y > rangey); + + Tile tile = world.tile(worldx, worldy); + + if(tile != null){ + Block block = tile.block(); + + if(!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)){ + block.drawShadow(tile); + } + + if(!(block instanceof StaticBlock)){ + if(block == Blocks.air){ + if(!state.is(State.paused)) tile.floor().update(tile); + }else{ + + if(!expanded){ + addRequest(tile, Layer.block); + } + + if(block.expanded || !expanded){ + if(block.layer != null && block.isLayer(tile)){ + addRequest(tile, block.layer); + } + + if(block.layer2 != null && block.isLayer2(tile)){ + addRequest(tile, block.layer2); + } + } + } + } + } + } + } + + Draw.color(0, 0, 0, 0.15f); + Graphics.flushSurface(); + Draw.color(); + + Graphics.end(); + drawCache(1, crangex, crangey); + Graphics.begin(); + + Arrays.sort(requests.items, 0, requestidx); + iterateidx = 0; + } + + public int getRequests(){ + return requestidx; + } + + public void drawBlocks(boolean top){ + Layer stopAt = top ? Layer.laser : Layer.overlay; + + for(; iterateidx < requestidx; iterateidx ++){ + + if(iterateidx < requests.size - 1 && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ + break; + } + + BlockRequest req = requests.get(iterateidx); + Block block = req.tile.block(); + + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); + } + } + } + + private void addRequest(Tile tile, Layer layer){ + if(requestidx >= requests.size){ + requests.add(new BlockRequest()); + } + BlockRequest r = requests.get(requestidx); + if(r == null){ + requests.set(requestidx, r = new BlockRequest()); + } + r.tile = tile; + r.layer = layer; + requestidx ++; + } + + public void drawFloor(){ + int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize; + + //render the entire map + if(cache == null || cache.length != chunksx || cache[0].length != chunksy){ + cache = new int[chunksx][chunksy][2]; + + for(int x = 0; x < chunksx; x++){ + for(int y = 0; y < chunksy; y++){ + cacheChunk(x, y, true); + cacheChunk(x, y, false); + } + } + } + + OrthographicCamera camera = Core.camera; + + if(Graphics.drawing()) Graphics.end(); + + int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; + int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; + + drawCache(0, crangex, crangey); + + Graphics.begin(); + + Draw.reset(); + + if(showPaths && debug){ + drawPaths(); + } + + if(debug && debugChunks){ + Draw.color(Color.YELLOW); + Lines.stroke(1f); + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ + int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; + int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; + + if(!Mathf.inBounds(worldx, worldy, cache)) + continue; + Lines.rect(worldx * chunksize * tilesize, worldy * chunksize * tilesize, chunksize * tilesize, chunksize * tilesize); + } + } + 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(int layer, int crangex, int crangey){ + Gdx.gl.glEnable(GL20.GL_BLEND); + + cbatch.setProjectionMatrix(Core.camera.combined); + cbatch.beginDraw(); + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ + int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; + int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; + + if(!Mathf.inBounds(worldx, worldy, cache)) + continue; + + cbatch.drawCache(cache[worldx][worldy][layer]); + } + } + + cbatch.endDraw(); + } + + void cacheChunk(int cx, int cy, boolean floor){ + if(cbatch == null){ + createBatch(); + } + + cbatch.begin(); + Graphics.useBatch(cbatch); + + for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ + for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ + Tile tile = world.tile(tilex, tiley); + if(tile == null) continue; + if(floor){ + if(!(tile.block() instanceof StaticBlock)){ + tile.floor().draw(tile); + } + }else if(tile.block() instanceof StaticBlock){ + tile.block().draw(tile); + } + } + } + Graphics.popBatch(); + cbatch.end(); + cache[cx][cy][floor ? 0 : 1] = cbatch.getLastCache(); + } + + public void clearTiles(){ + cache = null; + createBatch(); + } + + private void createBatch(){ + if(cbatch != null) + cbatch.dispose(); + cbatch = new CacheBatch(world.width() * world.height() * 4); + } + + public void drawPreview(Block block, float drawx, float drawy, float rotation, float opacity) { + Draw.reset(); + Draw.alpha(opacity); + Draw.rect(block.name(), drawx, drawy, rotation); + } + + public void handlePreview(Block block, float rotation, float drawx, float drawy, int tilex, int tiley) { + + if(control.input().recipe != null && state.inventory.hasItems(control.input().recipe.requirements) + && control.input().validPlace(tilex, tiley, block) && (android || control.input().cursorNear())) { + + float opacity = (float)Settings.getInt("previewopacity")/100f; + + if(block.isMultiblock()) { + if((tiley - control.input().getBlockY()) % block.height != 0 + || (tilex - control.input().getBlockX()) % block.width != 0) return; + } + + if(block instanceof Turret) { + Draw.alpha(opacity); + if (block.isMultiblock()) { + Draw.rect("block-" + block.width + "x" + block.height, drawx, drawy); + } else { + Draw.rect("block", drawx, drawy); + } + } + + drawPreview(block, drawx, drawy, rotation, opacity); + + Tile tile = world.tile(tilex, tiley); + if((block instanceof Drill || block instanceof Pump) && block.isLayer(tile)) { + block.drawLayer(tile); + } + + Draw.reset(); + } + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 0ac5439057..7c96d2dea2 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -7,6 +7,7 @@ import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.ui.fragments.ToolFragment; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.types.production.Drill; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; @@ -17,373 +18,379 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.*; public enum PlaceMode{ - cursor{ - { - shown = true; - lockCamera = true; - pan = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - float x = tilex * tilesize; - float y = tiley * tilesize; - - boolean valid = control.input().validPlace(tilex, tiley, control.input().recipe.result) && (android || control.input().cursorNear()); - - Vector2 offset = control.input().recipe.result.getPlaceOffset(); - - float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; - - Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); - Lines.stroke(2f); - Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, - tilesize * control.input().recipe.result.height + si); - - control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); - Lines.stroke(2f); - - if(control.input().recipe.result.rotate){ - Draw.color(Colors.get("placeRotate")); - tr.trns(control.input().rotation * 90, 7, 0); - Lines.line(x, y, x + tr.x, y + tr.y); - } - } - - public void tapped(int tilex, int tiley){ - control.input().tryPlaceBlock(tilex, tiley, true); - } - }, - touch{ - { - shown = true; - lockCamera = false; - showRotate = true; - showCancel = true; - } - - public void tapped(int x, int y){ - control.input().tryPlaceBlock(x, y, true); - } - }, - none{ - { - delete = true; - shown = true; - both = true; - } - }, - holdDelete{ - { - delete = true; - shown = true; - both = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - Tile tile = world.tile(tilex, tiley); - - if(tile != null && control.input().validBreak(tilex, tiley)){ - if(tile.isLinked()) - tile = tile.getLinked(); - float fin = control.input().breaktime / tile.getBreakTime(); - - if(android && control.input().breaktime > 0){ - Draw.color(Colors.get("breakStart"), Colors.get("break"), fin); - Lines.poly(tile.drawx(), tile.drawy(), 25, 4 + (1f - fin) * 26); - } - Draw.reset(); - } - } - }, - touchDelete{ - { - shown = true; - lockCamera = false; - showRotate = true; - showCancel = true; - delete = true; - } - - public void tapped(int x, int y){ - control.input().tryDeleteBlock(x, y, true); - } - }, - areaDelete{ - int maxlen = 20; - int tilex; - int tiley; - int endx; - int endy; - - { - shown = true; - lockCamera = true; - delete = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - float t = tilesize; - - process(tilex, tiley, endx, endy); - - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - float x = this.tilex * t, y = this.tiley * t, - x2 = this.endx * t, y2 = this.endy * t; - - if(x2 >= x){ - x -= t/2; - x2 += t/2; - } - - if(y2 >= y){ - y -= t/2; - y2 += t/2; - } - - Draw.color(Colors.get("break")); - Lines.stroke(1f); - for(int cx = tilex; cx <= endx; cx ++){ - for(int cy = tiley; cy <= endy; cy ++){ - Tile tile = world.tile(cx, cy); - if(tile != null && tile.getLinked() != null) - tile = tile.getLinked(); - if(tile != null && control.input().validBreak(tile.x, tile.y)){ - Lines.crect(tile.drawx(), tile.drawy(), - tile.block().width * t, tile.block().height * t); - } - } - } - - Lines.stroke(2f); - Draw.color(control.input().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); - Lines.rect(x, y, x2 - x, y2 - y); - Draw.alpha(0.3f); - Draw.crect("blank", x, y, x2 - x, y2 - y); - Draw.reset(); - } - - public void released(int tilex, int tiley, int endx, int endy){ - process(tilex, tiley, endx, endy); - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - - if(android){ - ToolFragment t = ui.toolfrag; - if(!t.confirming || t.px != tilex || t.py != tiley || t.px2 != endx || t.py2 != endy) { - t.confirming = true; - t.px = tilex; - t.py = tiley; - t.px2 = endx; - t.py2 = endy; - return; - } - } - - boolean first = true; - - for(int cx = tilex; cx <= endx; cx ++){ - for(int cy = tiley; cy <= endy; cy ++){ - if(control.input().tryDeleteBlock(cx, cy, first)){ - first = false; - } - } - } - } - - void process(int tilex, int tiley, int endx, int endy){ - - if(Math.abs(endx - tilex) > maxlen){ - endx = Mathf.sign(endx - tilex) * maxlen + tilex; - } - - if(Math.abs(endy - tiley) > maxlen){ - endy = Mathf.sign(endy - tiley) * maxlen + tiley; - } - - if(endx < tilex){ - int t = endx; - endx = tilex; - tilex = t; - } - if(endy < tiley){ - int t = endy; - endy = tiley; - tiley = t; - } - - this.endx = endx; - this.endy = endy; - this.tilex = tilex; - this.tiley = tiley; - } - }, - hold{ - int maxlen = 20; - int tilex; - int tiley; - int endx; - int endy; - int rotation; - - { - lockCamera = true; - shown = true; - showCancel = true; - showRotate = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - if(android && !Gdx.input.isTouched(0) && !control.showCursor()){ - return; - } - - float t = tilesize; - Block block = control.input().recipe.result; - Vector2 offset = block.getPlaceOffset(); - - process(tilex, tiley, endx, endy); - int tx = tilex, ty = tiley, ex = endx, ey = endy; - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - float x = this.tilex * t, y = this.tiley * t, - x2 = this.endx * t, y2 = this.endy * t; - - if(x2 >= x){ - x -= block.width * t/2; - x2 += block.width * t/2; - } - - if(y2 >= y){ - y -= block.height * t/2; - y2 += block.height * t/2; - } - - x += offset.x; - y += offset.y; - x2 += offset.x; - y2 += offset.y; - - if(tilex == endx && tiley == endy){ - cursor.draw(tilex, tiley, endx, endy); - }else{ - Lines.stroke(2f); - Draw.color(control.input().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); - Lines.rect(x, y, x2 - x, y2 - y); - Draw.alpha(0.3f); - Draw.crect("blank", x, y, x2 - x, y2 - y); - - Draw.color(Colors.get("placeInvalid")); - - int amount = 1; - for(int cx = 0; cx <= Math.abs(endx - tilex); cx ++){ - for(int cy = 0; cy <= Math.abs(endy - tiley); cy ++){ - int px = tx + cx * Mathf.sign(ex - tx), - py = ty + cy * Mathf.sign(ey - ty); - - if(!control.input().validPlace(px, py, control.input().recipe.result) - || !state.inventory.hasItems(control.input().recipe.requirements, amount)){ - Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); - } - amount ++; - } - } - - if(control.input().recipe.result.rotate){ - float cx = tx * t, cy = ty * t; - Draw.color(Colors.get("placeRotate")); - tr.trns(rotation * 90, 7, 0); - Lines.line(cx, cy, cx + tr.x, cy + tr.y); - } - Draw.reset(); - } - } - - public void released(int tilex, int tiley, int endx, int endy){ - process(tilex, tiley, endx, endy); - - control.input().rotation = this.rotation; - - boolean first = true; - for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ - for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ - if(control.input().tryPlaceBlock( - tilex + x * Mathf.sign(endx - tilex), - tiley + y * Mathf.sign(endy - tiley), first)){ - first = false; - } - - } - } - } - - void process(int tilex, int tiley, int endx, int endy){ - if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ - endy = tiley; - }else{ - endx = tilex; - } - - if(Math.abs(endx - tilex) > maxlen){ - endx = Mathf.sign(endx - tilex) * maxlen + tilex; - } - - if(Math.abs(endy - tiley) > maxlen){ - endy = Mathf.sign(endy - tiley) * maxlen + tiley; - } - - if(endx > tilex) - rotation = 0; - else if(endx < tilex) - rotation = 2; - else if(endy > tiley) - rotation = 1; - else if(endy < tiley) - rotation = 3; - else - rotation = control.input().rotation; - - if(endx < tilex){ - int t = endx; - endx = tilex; - tilex = t; - } - if(endy < tiley){ - int t = endy; - endy = tiley; - tiley = t; - } - - this.endx = endx; - this.endy = endy; - this.tilex = tilex; - this.tiley = tiley; - } - }; - public boolean lockCamera; - public boolean pan = false; - public boolean shown = false; - public boolean showRotate; - public boolean showCancel; - public boolean delete = false; - public boolean both = false; - - private static final Translator tr = new Translator(); - - public void draw(int tilex, int tiley, int endx, int endy){ - - } - - public void released(int tilex, int tiley, int endx, int endy){ - - } - - public void tapped(int x, int y){ - - } - - @Override - public String toString(){ - return Bundles.get("placemode."+name().toLowerCase()+".name"); - } -} + cursor{ + { + shown = true; + lockCamera = true; + pan = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + float x = tilex * tilesize; + float y = tiley * tilesize; + + boolean valid = control.input().validPlace(tilex, tiley, control.input().recipe.result) && (android || control.input().cursorNear()); + + Vector2 offset = control.input().recipe.result.getPlaceOffset(); + + float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; + + Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); + Lines.stroke(2f); + Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, + tilesize * control.input().recipe.result.height + si); + + control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); + + renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? control.input().rotation * 90 : 0f, x + offset.x, y + offset.y, tilex, tiley); + + if(control.input().recipe.result.rotate){ + + Draw.color(Colors.get("placeRotate")); + tr.trns(control.input().rotation * 90, 7, 0); + Lines.stroke(2f); + Lines.line(x, y, x + tr.x, y + tr.y); + } + } + + public void tapped(int tilex, int tiley){ + control.input().tryPlaceBlock(tilex, tiley, true); + } + }, + touch{ + { + shown = true; + lockCamera = false; + showRotate = true; + showCancel = true; + } + + public void tapped(int x, int y){ + control.input().tryPlaceBlock(x, y, true); + } + }, + none{ + { + delete = true; + shown = true; + both = true; + } + }, + holdDelete{ + { + delete = true; + shown = true; + both = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + Tile tile = world.tile(tilex, tiley); + + if(tile != null && control.input().validBreak(tilex, tiley)){ + if(tile.isLinked()) + tile = tile.getLinked(); + float fin = control.input().breaktime / tile.getBreakTime(); + + if(android && control.input().breaktime > 0){ + Draw.color(Colors.get("breakStart"), Colors.get("break"), fin); + Lines.poly(tile.drawx(), tile.drawy(), 25, 4 + (1f - fin) * 26); + } + Draw.reset(); + } + } + }, + touchDelete{ + { + shown = true; + lockCamera = false; + showRotate = true; + showCancel = true; + delete = true; + } + + public void tapped(int x, int y){ + control.input().tryDeleteBlock(x, y, true); + } + }, + areaDelete{ + int maxlen = 20; + int tilex; + int tiley; + int endx; + int endy; + + { + shown = true; + lockCamera = true; + delete = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + float t = tilesize; + + process(tilex, tiley, endx, endy); + + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + float x = this.tilex * t, y = this.tiley * t, + x2 = this.endx * t, y2 = this.endy * t; + + if(x2 >= x){ + x -= t/2; + x2 += t/2; + } + + if(y2 >= y){ + y -= t/2; + y2 += t/2; + } + + Draw.color(Colors.get("break")); + Lines.stroke(1f); + for(int cx = tilex; cx <= endx; cx ++){ + for(int cy = tiley; cy <= endy; cy ++){ + Tile tile = world.tile(cx, cy); + if(tile != null && tile.getLinked() != null) + tile = tile.getLinked(); + if(tile != null && control.input().validBreak(tile.x, tile.y)){ + Lines.crect(tile.drawx(), tile.drawy(), + tile.block().width * t, tile.block().height * t); + } + } + } + + Lines.stroke(2f); + Draw.color(control.input().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); + Lines.rect(x, y, x2 - x, y2 - y); + Draw.alpha(0.3f); + Draw.crect("blank", x, y, x2 - x, y2 - y); + Draw.reset(); + } + + public void released(int tilex, int tiley, int endx, int endy){ + process(tilex, tiley, endx, endy); + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + + if(android){ + ToolFragment t = ui.toolfrag; + if(!t.confirming || t.px != tilex || t.py != tiley || t.px2 != endx || t.py2 != endy) { + t.confirming = true; + t.px = tilex; + t.py = tiley; + t.px2 = endx; + t.py2 = endy; + return; + } + } + + boolean first = true; + + for(int cx = tilex; cx <= endx; cx ++){ + for(int cy = tiley; cy <= endy; cy ++){ + if(control.input().tryDeleteBlock(cx, cy, first)){ + first = false; + } + } + } + } + + void process(int tilex, int tiley, int endx, int endy){ + + if(Math.abs(endx - tilex) > maxlen){ + endx = Mathf.sign(endx - tilex) * maxlen + tilex; + } + + if(Math.abs(endy - tiley) > maxlen){ + endy = Mathf.sign(endy - tiley) * maxlen + tiley; + } + + if(endx < tilex){ + int t = endx; + endx = tilex; + tilex = t; + } + if(endy < tiley){ + int t = endy; + endy = tiley; + tiley = t; + } + + this.endx = endx; + this.endy = endy; + this.tilex = tilex; + this.tiley = tiley; + } + }, + hold{ + int maxlen = 20; + int tilex; + int tiley; + int endx; + int endy; + int rotation; + + { + lockCamera = true; + shown = true; + showCancel = true; + showRotate = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + if(android && !Gdx.input.isTouched(0) && !control.showCursor()){ + return; + } + + float t = tilesize; + Block block = control.input().recipe.result; + Vector2 offset = block.getPlaceOffset(); + + process(tilex, tiley, endx, endy); + int tx = tilex, ty = tiley, ex = endx, ey = endy; + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + float x = this.tilex * t, y = this.tiley * t, + x2 = this.endx * t, y2 = this.endy * t; + + if(x2 >= x){ + x -= block.width * t/2; + x2 += block.width * t/2; + } + + if(y2 >= y){ + y -= block.height * t/2; + y2 += block.height * t/2; + } + + x += offset.x; + y += offset.y; + x2 += offset.x; + y2 += offset.y; + + if(tilex == endx && tiley == endy){ + cursor.draw(tilex, tiley, endx, endy); + }else{ + Lines.stroke(2f); + Draw.color(control.input().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); + Lines.rect(x, y, x2 - x, y2 - y); + Draw.alpha(0.3f); + Draw.crect("blank", x, y, x2 - x, y2 - y); + + Draw.color(Colors.get("placeInvalid")); + + int amount = 1; + for(int cx = 0; cx <= Math.abs(endx - tilex); cx ++){ + for(int cy = 0; cy <= Math.abs(endy - tiley); cy ++){ + int px = tx + cx * Mathf.sign(ex - tx), + py = ty + cy * Mathf.sign(ey - ty); + + renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? rotation * 90 : 0f, px * t + offset.x, py * t + offset.y, px, py); + + if(!control.input().validPlace(px, py, control.input().recipe.result) + || !state.inventory.hasItems(control.input().recipe.requirements, amount)) + Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); + + amount ++; + } + } + + if(control.input().recipe.result.rotate){ + float cx = tx * t, cy = ty * t; + Lines.stroke(2f); + Draw.color(Colors.get("placeRotate")); + tr.trns(rotation * 90, 7, 0); + Lines.line(cx, cy, cx + tr.x, cy + tr.y); + } + Draw.reset(); + } + } + + public void released(int tilex, int tiley, int endx, int endy){ + process(tilex, tiley, endx, endy); + + control.input().rotation = this.rotation; + + boolean first = true; + for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ + for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ + if(control.input().tryPlaceBlock( + tilex + x * Mathf.sign(endx - tilex), + tiley + y * Mathf.sign(endy - tiley), first)){ + first = false; + } + + } + } + } + + void process(int tilex, int tiley, int endx, int endy){ + if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ + endy = tiley; + }else{ + endx = tilex; + } + + if(Math.abs(endx - tilex) > maxlen){ + endx = Mathf.sign(endx - tilex) * maxlen + tilex; + } + + if(Math.abs(endy - tiley) > maxlen){ + endy = Mathf.sign(endy - tiley) * maxlen + tiley; + } + + if(endx > tilex) + rotation = 0; + else if(endx < tilex) + rotation = 2; + else if(endy > tiley) + rotation = 1; + else if(endy < tiley) + rotation = 3; + else + rotation = control.input().rotation; + + if(endx < tilex){ + int t = endx; + endx = tilex; + tilex = t; + } + if(endy < tiley){ + int t = endy; + endy = tiley; + tiley = t; + } + + this.endx = endx; + this.endy = endy; + this.tilex = tilex; + this.tiley = tiley; + } + }; + public boolean lockCamera; + public boolean pan = false; + public boolean shown = false; + public boolean showRotate; + public boolean showCancel; + public boolean delete = false; + public boolean both = false; + + private static final Translator tr = new Translator(); + + public void draw(int tilex, int tiley, int endx, int endy){ + + } + + public void released(int tilex, int tiley, int endx, int endy){ + + } + + public void tapped(int x, int y){ + + } + + @Override + public String toString(){ + return Bundles.get("placemode."+name().toLowerCase()+".name"); + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 6d2e79c610..895122b158 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -139,6 +139,7 @@ public class SettingsMenuDialog extends SettingsDialog{ graphics.checkPref("fps", false); graphics.checkPref("lasers", true); + graphics.sliderPref("previewopacity", 50, 0, 100, i -> i + "%"); graphics.checkPref("indicators", true); graphics.checkPref("healthbars", true); graphics.checkPref("pixelate", true, b -> { From 494e415bd34b65a512d97412e0190cbea0d3268f Mon Sep 17 00:00:00 2001 From: Commodore64x Date: Sun, 15 Apr 2018 19:53:23 +1000 Subject: [PATCH 03/18] Fixed formatting? --- .../mindustry/graphics/BlockRenderer.java | 586 +++++++------- .../io/anuke/mindustry/input/PlaceMode.java | 750 +++++++++--------- 2 files changed, 668 insertions(+), 668 deletions(-) diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 84e3cf8b17..4d1b962da1 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -29,297 +29,297 @@ import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.core.Core.camera; public class BlockRenderer{ - private final static int chunksize = 32; - private final static int initialRequests = 32*32; - - private int[][][] cache; - private CacheBatch cbatch; - - private Array requests = new Array(initialRequests); - private int requestidx = 0; - private int iterateidx = 0; - - public BlockRenderer(){ - for(int i = 0; i < requests.size; i ++){ - requests.set(i, new BlockRequest()); - } - } - - private class BlockRequest implements Comparable{ - Tile tile; - Layer layer; - - @Override - public int compareTo(BlockRequest other){ - return layer.compareTo(other.layer); - } - - @Override - public String toString(){ - return tile.block().name + ":" + layer.toString(); - } - } - - /**Process all blocks to draw, simultaneously drawing block shadows and static blocks.*/ - public void processBlocks(){ - requestidx = 0; - - int crangex = (int) (camera.viewportWidth / (chunksize * tilesize)) + 1; - int crangey = (int) (camera.viewportHeight / (chunksize * tilesize)) + 1; - - int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2)+2; - int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2)+2; - - int expandr = 3; - - Graphics.surface(renderer.shadowSurface); - - for(int x = -rangex - expandr; x <= rangex + expandr; x++){ - for(int y = -rangey - expandr; y <= rangey + expandr; y++){ - int worldx = Mathf.scl(camera.position.x, tilesize) + x; - int worldy = Mathf.scl(camera.position.y, tilesize) + y; - boolean expanded = (x < -rangex || x > rangex || y < -rangey || y > rangey); - - Tile tile = world.tile(worldx, worldy); - - if(tile != null){ - Block block = tile.block(); - - if(!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)){ - block.drawShadow(tile); - } - - if(!(block instanceof StaticBlock)){ - if(block == Blocks.air){ - if(!state.is(State.paused)) tile.floor().update(tile); - }else{ - - if(!expanded){ - addRequest(tile, Layer.block); - } - - if(block.expanded || !expanded){ - if(block.layer != null && block.isLayer(tile)){ - addRequest(tile, block.layer); - } - - if(block.layer2 != null && block.isLayer2(tile)){ - addRequest(tile, block.layer2); - } - } - } - } - } - } - } - - Draw.color(0, 0, 0, 0.15f); - Graphics.flushSurface(); - Draw.color(); - - Graphics.end(); - drawCache(1, crangex, crangey); - Graphics.begin(); - - Arrays.sort(requests.items, 0, requestidx); - iterateidx = 0; - } - - public int getRequests(){ - return requestidx; - } - - public void drawBlocks(boolean top){ - Layer stopAt = top ? Layer.laser : Layer.overlay; - - for(; iterateidx < requestidx; iterateidx ++){ - - if(iterateidx < requests.size - 1 && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ - break; - } - - BlockRequest req = requests.get(iterateidx); - Block block = req.tile.block(); - - if(req.layer == Layer.block){ - block.draw(req.tile); - }else if(req.layer == block.layer){ - block.drawLayer(req.tile); - }else if(req.layer == block.layer2){ - block.drawLayer2(req.tile); - } - } - } - - private void addRequest(Tile tile, Layer layer){ - if(requestidx >= requests.size){ - requests.add(new BlockRequest()); - } - BlockRequest r = requests.get(requestidx); - if(r == null){ - requests.set(requestidx, r = new BlockRequest()); - } - r.tile = tile; - r.layer = layer; - requestidx ++; - } - - public void drawFloor(){ - int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize; - - //render the entire map - if(cache == null || cache.length != chunksx || cache[0].length != chunksy){ - cache = new int[chunksx][chunksy][2]; - - for(int x = 0; x < chunksx; x++){ - for(int y = 0; y < chunksy; y++){ - cacheChunk(x, y, true); - cacheChunk(x, y, false); - } - } - } - - OrthographicCamera camera = Core.camera; - - if(Graphics.drawing()) Graphics.end(); - - int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; - int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; - - drawCache(0, crangex, crangey); - - Graphics.begin(); - - Draw.reset(); - - if(showPaths && debug){ - drawPaths(); - } - - if(debug && debugChunks){ - Draw.color(Color.YELLOW); - Lines.stroke(1f); - for(int x = -crangex; x <= crangex; x++){ - for(int y = -crangey; y <= crangey; y++){ - int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; - int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; - - if(!Mathf.inBounds(worldx, worldy, cache)) - continue; - Lines.rect(worldx * chunksize * tilesize, worldy * chunksize * tilesize, chunksize * tilesize, chunksize * tilesize); - } - } - 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(int layer, int crangex, int crangey){ - Gdx.gl.glEnable(GL20.GL_BLEND); - - cbatch.setProjectionMatrix(Core.camera.combined); - cbatch.beginDraw(); - for(int x = -crangex; x <= crangex; x++){ - for(int y = -crangey; y <= crangey; y++){ - int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; - int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; - - if(!Mathf.inBounds(worldx, worldy, cache)) - continue; - - cbatch.drawCache(cache[worldx][worldy][layer]); - } - } - - cbatch.endDraw(); - } - - void cacheChunk(int cx, int cy, boolean floor){ - if(cbatch == null){ - createBatch(); - } - - cbatch.begin(); - Graphics.useBatch(cbatch); - - for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ - for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ - Tile tile = world.tile(tilex, tiley); - if(tile == null) continue; - if(floor){ - if(!(tile.block() instanceof StaticBlock)){ - tile.floor().draw(tile); - } - }else if(tile.block() instanceof StaticBlock){ - tile.block().draw(tile); - } - } - } - Graphics.popBatch(); - cbatch.end(); - cache[cx][cy][floor ? 0 : 1] = cbatch.getLastCache(); - } - - public void clearTiles(){ - cache = null; - createBatch(); - } - - private void createBatch(){ - if(cbatch != null) - cbatch.dispose(); - cbatch = new CacheBatch(world.width() * world.height() * 4); - } - - public void drawPreview(Block block, float drawx, float drawy, float rotation, float opacity) { - Draw.reset(); - Draw.alpha(opacity); - Draw.rect(block.name(), drawx, drawy, rotation); - } - - public void handlePreview(Block block, float rotation, float drawx, float drawy, int tilex, int tiley) { - - if(control.input().recipe != null && state.inventory.hasItems(control.input().recipe.requirements) - && control.input().validPlace(tilex, tiley, block) && (android || control.input().cursorNear())) { - - float opacity = (float)Settings.getInt("previewopacity")/100f; - - if(block.isMultiblock()) { - if((tiley - control.input().getBlockY()) % block.height != 0 - || (tilex - control.input().getBlockX()) % block.width != 0) return; - } - - if(block instanceof Turret) { - Draw.alpha(opacity); - if (block.isMultiblock()) { - Draw.rect("block-" + block.width + "x" + block.height, drawx, drawy); - } else { - Draw.rect("block", drawx, drawy); - } - } - - drawPreview(block, drawx, drawy, rotation, opacity); - - Tile tile = world.tile(tilex, tiley); - if((block instanceof Drill || block instanceof Pump) && block.isLayer(tile)) { - block.drawLayer(tile); - } - - Draw.reset(); - } - } + private final static int chunksize = 32; + private final static int initialRequests = 32*32; + + private int[][][] cache; + private CacheBatch cbatch; + + private Array requests = new Array(initialRequests); + private int requestidx = 0; + private int iterateidx = 0; + + public BlockRenderer(){ + for(int i = 0; i < requests.size; i ++){ + requests.set(i, new BlockRequest()); + } + } + + private class BlockRequest implements Comparable{ + Tile tile; + Layer layer; + + @Override + public int compareTo(BlockRequest other){ + return layer.compareTo(other.layer); + } + + @Override + public String toString(){ + return tile.block().name + ":" + layer.toString(); + } + } + + /**Process all blocks to draw, simultaneously drawing block shadows and static blocks.*/ + public void processBlocks(){ + requestidx = 0; + + int crangex = (int) (camera.viewportWidth / (chunksize * tilesize)) + 1; + int crangey = (int) (camera.viewportHeight / (chunksize * tilesize)) + 1; + + int rangex = (int) (camera.viewportWidth * camera.zoom / tilesize / 2)+2; + int rangey = (int) (camera.viewportHeight * camera.zoom / tilesize / 2)+2; + + int expandr = 3; + + Graphics.surface(renderer.shadowSurface); + + for(int x = -rangex - expandr; x <= rangex + expandr; x++){ + for(int y = -rangey - expandr; y <= rangey + expandr; y++){ + int worldx = Mathf.scl(camera.position.x, tilesize) + x; + int worldy = Mathf.scl(camera.position.y, tilesize) + y; + boolean expanded = (x < -rangex || x > rangex || y < -rangey || y > rangey); + + Tile tile = world.tile(worldx, worldy); + + if(tile != null){ + Block block = tile.block(); + + if(!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)){ + block.drawShadow(tile); + } + + if(!(block instanceof StaticBlock)){ + if(block == Blocks.air){ + if(!state.is(State.paused)) tile.floor().update(tile); + }else{ + + if(!expanded){ + addRequest(tile, Layer.block); + } + + if(block.expanded || !expanded){ + if(block.layer != null && block.isLayer(tile)){ + addRequest(tile, block.layer); + } + + if(block.layer2 != null && block.isLayer2(tile)){ + addRequest(tile, block.layer2); + } + } + } + } + } + } + } + + Draw.color(0, 0, 0, 0.15f); + Graphics.flushSurface(); + Draw.color(); + + Graphics.end(); + drawCache(1, crangex, crangey); + Graphics.begin(); + + Arrays.sort(requests.items, 0, requestidx); + iterateidx = 0; + } + + public int getRequests(){ + return requestidx; + } + + public void drawBlocks(boolean top){ + Layer stopAt = top ? Layer.laser : Layer.overlay; + + for(; iterateidx < requestidx; iterateidx ++){ + + if(iterateidx < requests.size - 1 && requests.get(iterateidx).layer.ordinal() > stopAt.ordinal()){ + break; + } + + BlockRequest req = requests.get(iterateidx); + Block block = req.tile.block(); + + if(req.layer == Layer.block){ + block.draw(req.tile); + }else if(req.layer == block.layer){ + block.drawLayer(req.tile); + }else if(req.layer == block.layer2){ + block.drawLayer2(req.tile); + } + } + } + + private void addRequest(Tile tile, Layer layer){ + if(requestidx >= requests.size){ + requests.add(new BlockRequest()); + } + BlockRequest r = requests.get(requestidx); + if(r == null){ + requests.set(requestidx, r = new BlockRequest()); + } + r.tile = tile; + r.layer = layer; + requestidx ++; + } + + public void drawFloor(){ + int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize; + + //render the entire map + if(cache == null || cache.length != chunksx || cache[0].length != chunksy){ + cache = new int[chunksx][chunksy][2]; + + for(int x = 0; x < chunksx; x++){ + for(int y = 0; y < chunksy; y++){ + cacheChunk(x, y, true); + cacheChunk(x, y, false); + } + } + } + + OrthographicCamera camera = Core.camera; + + if(Graphics.drawing()) Graphics.end(); + + int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1; + int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1; + + drawCache(0, crangex, crangey); + + Graphics.begin(); + + Draw.reset(); + + if(showPaths && debug){ + drawPaths(); + } + + if(debug && debugChunks){ + Draw.color(Color.YELLOW); + Lines.stroke(1f); + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ + int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; + int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; + + if(!Mathf.inBounds(worldx, worldy, cache)) + continue; + Lines.rect(worldx * chunksize * tilesize, worldy * chunksize * tilesize, chunksize * tilesize, chunksize * tilesize); + } + } + 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(int layer, int crangex, int crangey){ + Gdx.gl.glEnable(GL20.GL_BLEND); + + cbatch.setProjectionMatrix(Core.camera.combined); + cbatch.beginDraw(); + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ + int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; + int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; + + if(!Mathf.inBounds(worldx, worldy, cache)) + continue; + + cbatch.drawCache(cache[worldx][worldy][layer]); + } + } + + cbatch.endDraw(); + } + + void cacheChunk(int cx, int cy, boolean floor){ + if(cbatch == null){ + createBatch(); + } + + cbatch.begin(); + Graphics.useBatch(cbatch); + + for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ + for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ + Tile tile = world.tile(tilex, tiley); + if(tile == null) continue; + if(floor){ + if(!(tile.block() instanceof StaticBlock)){ + tile.floor().draw(tile); + } + }else if(tile.block() instanceof StaticBlock){ + tile.block().draw(tile); + } + } + } + Graphics.popBatch(); + cbatch.end(); + cache[cx][cy][floor ? 0 : 1] = cbatch.getLastCache(); + } + + public void clearTiles(){ + cache = null; + createBatch(); + } + + private void createBatch(){ + if(cbatch != null) + cbatch.dispose(); + cbatch = new CacheBatch(world.width() * world.height() * 4); + } + + public void drawPreview(Block block, float drawx, float drawy, float rotation, float opacity) { + Draw.reset(); + Draw.alpha(opacity); + Draw.rect(block.name(), drawx, drawy, rotation); + } + + public void handlePreview(Block block, float rotation, float drawx, float drawy, int tilex, int tiley) { + + if(control.input().recipe != null && state.inventory.hasItems(control.input().recipe.requirements) + && control.input().validPlace(tilex, tiley, block) && (android || control.input().cursorNear())) { + + float opacity = (float)Settings.getInt("previewopacity")/100f; + + if(block.isMultiblock()) { + if((tiley - control.input().getBlockY()) % block.height != 0 + || (tilex - control.input().getBlockX()) % block.width != 0) return; + } + + if(block instanceof Turret) { + Draw.alpha(opacity); + if (block.isMultiblock()) { + Draw.rect("block-" + block.width + "x" + block.height, drawx, drawy); + } else { + Draw.rect("block", drawx, drawy); + } + } + + drawPreview(block, drawx, drawy, rotation, opacity); + + Tile tile = world.tile(tilex, tiley); + if((block instanceof Drill || block instanceof Pump) && block.isLayer(tile)) { + block.drawLayer(tile); + } + + Draw.reset(); + } + } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 7c96d2dea2..3aaf5de822 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -18,379 +18,379 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.*; public enum PlaceMode{ - cursor{ - { - shown = true; - lockCamera = true; - pan = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - float x = tilex * tilesize; - float y = tiley * tilesize; - - boolean valid = control.input().validPlace(tilex, tiley, control.input().recipe.result) && (android || control.input().cursorNear()); - - Vector2 offset = control.input().recipe.result.getPlaceOffset(); - - float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; - - Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); - Lines.stroke(2f); - Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, - tilesize * control.input().recipe.result.height + si); - - control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); - - renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? control.input().rotation * 90 : 0f, x + offset.x, y + offset.y, tilex, tiley); - - if(control.input().recipe.result.rotate){ - - Draw.color(Colors.get("placeRotate")); - tr.trns(control.input().rotation * 90, 7, 0); - Lines.stroke(2f); - Lines.line(x, y, x + tr.x, y + tr.y); - } - } - - public void tapped(int tilex, int tiley){ - control.input().tryPlaceBlock(tilex, tiley, true); - } - }, - touch{ - { - shown = true; - lockCamera = false; - showRotate = true; - showCancel = true; - } - - public void tapped(int x, int y){ - control.input().tryPlaceBlock(x, y, true); - } - }, - none{ - { - delete = true; - shown = true; - both = true; - } - }, - holdDelete{ - { - delete = true; - shown = true; - both = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - Tile tile = world.tile(tilex, tiley); - - if(tile != null && control.input().validBreak(tilex, tiley)){ - if(tile.isLinked()) - tile = tile.getLinked(); - float fin = control.input().breaktime / tile.getBreakTime(); - - if(android && control.input().breaktime > 0){ - Draw.color(Colors.get("breakStart"), Colors.get("break"), fin); - Lines.poly(tile.drawx(), tile.drawy(), 25, 4 + (1f - fin) * 26); - } - Draw.reset(); - } - } - }, - touchDelete{ - { - shown = true; - lockCamera = false; - showRotate = true; - showCancel = true; - delete = true; - } - - public void tapped(int x, int y){ - control.input().tryDeleteBlock(x, y, true); - } - }, - areaDelete{ - int maxlen = 20; - int tilex; - int tiley; - int endx; - int endy; - - { - shown = true; - lockCamera = true; - delete = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - float t = tilesize; - - process(tilex, tiley, endx, endy); - - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - float x = this.tilex * t, y = this.tiley * t, - x2 = this.endx * t, y2 = this.endy * t; - - if(x2 >= x){ - x -= t/2; - x2 += t/2; - } - - if(y2 >= y){ - y -= t/2; - y2 += t/2; - } - - Draw.color(Colors.get("break")); - Lines.stroke(1f); - for(int cx = tilex; cx <= endx; cx ++){ - for(int cy = tiley; cy <= endy; cy ++){ - Tile tile = world.tile(cx, cy); - if(tile != null && tile.getLinked() != null) - tile = tile.getLinked(); - if(tile != null && control.input().validBreak(tile.x, tile.y)){ - Lines.crect(tile.drawx(), tile.drawy(), - tile.block().width * t, tile.block().height * t); - } - } - } - - Lines.stroke(2f); - Draw.color(control.input().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); - Lines.rect(x, y, x2 - x, y2 - y); - Draw.alpha(0.3f); - Draw.crect("blank", x, y, x2 - x, y2 - y); - Draw.reset(); - } - - public void released(int tilex, int tiley, int endx, int endy){ - process(tilex, tiley, endx, endy); - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - - if(android){ - ToolFragment t = ui.toolfrag; - if(!t.confirming || t.px != tilex || t.py != tiley || t.px2 != endx || t.py2 != endy) { - t.confirming = true; - t.px = tilex; - t.py = tiley; - t.px2 = endx; - t.py2 = endy; - return; - } - } - - boolean first = true; - - for(int cx = tilex; cx <= endx; cx ++){ - for(int cy = tiley; cy <= endy; cy ++){ - if(control.input().tryDeleteBlock(cx, cy, first)){ - first = false; - } - } - } - } - - void process(int tilex, int tiley, int endx, int endy){ - - if(Math.abs(endx - tilex) > maxlen){ - endx = Mathf.sign(endx - tilex) * maxlen + tilex; - } - - if(Math.abs(endy - tiley) > maxlen){ - endy = Mathf.sign(endy - tiley) * maxlen + tiley; - } - - if(endx < tilex){ - int t = endx; - endx = tilex; - tilex = t; - } - if(endy < tiley){ - int t = endy; - endy = tiley; - tiley = t; - } - - this.endx = endx; - this.endy = endy; - this.tilex = tilex; - this.tiley = tiley; - } - }, - hold{ - int maxlen = 20; - int tilex; - int tiley; - int endx; - int endy; - int rotation; - - { - lockCamera = true; - shown = true; - showCancel = true; - showRotate = true; - } - - public void draw(int tilex, int tiley, int endx, int endy){ - if(android && !Gdx.input.isTouched(0) && !control.showCursor()){ - return; - } - - float t = tilesize; - Block block = control.input().recipe.result; - Vector2 offset = block.getPlaceOffset(); - - process(tilex, tiley, endx, endy); - int tx = tilex, ty = tiley, ex = endx, ey = endy; - tilex = this.tilex; tiley = this.tiley; - endx = this.endx; endy = this.endy; - float x = this.tilex * t, y = this.tiley * t, - x2 = this.endx * t, y2 = this.endy * t; - - if(x2 >= x){ - x -= block.width * t/2; - x2 += block.width * t/2; - } - - if(y2 >= y){ - y -= block.height * t/2; - y2 += block.height * t/2; - } - - x += offset.x; - y += offset.y; - x2 += offset.x; - y2 += offset.y; - - if(tilex == endx && tiley == endy){ - cursor.draw(tilex, tiley, endx, endy); - }else{ - Lines.stroke(2f); - Draw.color(control.input().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); - Lines.rect(x, y, x2 - x, y2 - y); - Draw.alpha(0.3f); - Draw.crect("blank", x, y, x2 - x, y2 - y); - - Draw.color(Colors.get("placeInvalid")); - - int amount = 1; - for(int cx = 0; cx <= Math.abs(endx - tilex); cx ++){ - for(int cy = 0; cy <= Math.abs(endy - tiley); cy ++){ - int px = tx + cx * Mathf.sign(ex - tx), - py = ty + cy * Mathf.sign(ey - ty); - - renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? rotation * 90 : 0f, px * t + offset.x, py * t + offset.y, px, py); - - if(!control.input().validPlace(px, py, control.input().recipe.result) - || !state.inventory.hasItems(control.input().recipe.requirements, amount)) - Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); - - amount ++; - } - } - - if(control.input().recipe.result.rotate){ - float cx = tx * t, cy = ty * t; - Lines.stroke(2f); - Draw.color(Colors.get("placeRotate")); - tr.trns(rotation * 90, 7, 0); - Lines.line(cx, cy, cx + tr.x, cy + tr.y); - } - Draw.reset(); - } - } - - public void released(int tilex, int tiley, int endx, int endy){ - process(tilex, tiley, endx, endy); - - control.input().rotation = this.rotation; - - boolean first = true; - for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ - for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ - if(control.input().tryPlaceBlock( - tilex + x * Mathf.sign(endx - tilex), - tiley + y * Mathf.sign(endy - tiley), first)){ - first = false; - } - - } - } - } - - void process(int tilex, int tiley, int endx, int endy){ - if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ - endy = tiley; - }else{ - endx = tilex; - } - - if(Math.abs(endx - tilex) > maxlen){ - endx = Mathf.sign(endx - tilex) * maxlen + tilex; - } - - if(Math.abs(endy - tiley) > maxlen){ - endy = Mathf.sign(endy - tiley) * maxlen + tiley; - } - - if(endx > tilex) - rotation = 0; - else if(endx < tilex) - rotation = 2; - else if(endy > tiley) - rotation = 1; - else if(endy < tiley) - rotation = 3; - else - rotation = control.input().rotation; - - if(endx < tilex){ - int t = endx; - endx = tilex; - tilex = t; - } - if(endy < tiley){ - int t = endy; - endy = tiley; - tiley = t; - } - - this.endx = endx; - this.endy = endy; - this.tilex = tilex; - this.tiley = tiley; - } - }; - public boolean lockCamera; - public boolean pan = false; - public boolean shown = false; - public boolean showRotate; - public boolean showCancel; - public boolean delete = false; - public boolean both = false; - - private static final Translator tr = new Translator(); - - public void draw(int tilex, int tiley, int endx, int endy){ - - } - - public void released(int tilex, int tiley, int endx, int endy){ - - } - - public void tapped(int x, int y){ - - } - - @Override - public String toString(){ - return Bundles.get("placemode."+name().toLowerCase()+".name"); - } + cursor{ + { + shown = true; + lockCamera = true; + pan = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + float x = tilex * tilesize; + float y = tiley * tilesize; + + boolean valid = control.input().validPlace(tilex, tiley, control.input().recipe.result) && (android || control.input().cursorNear()); + + Vector2 offset = control.input().recipe.result.getPlaceOffset(); + + float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; + + Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); + Lines.stroke(2f); + Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, + tilesize * control.input().recipe.result.height + si); + + control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); + + renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? control.input().rotation * 90 : 0f, x + offset.x, y + offset.y, tilex, tiley); + + if(control.input().recipe.result.rotate){ + + Draw.color(Colors.get("placeRotate")); + tr.trns(control.input().rotation * 90, 7, 0); + Lines.stroke(2f); + Lines.line(x, y, x + tr.x, y + tr.y); + } + } + + public void tapped(int tilex, int tiley){ + control.input().tryPlaceBlock(tilex, tiley, true); + } + }, + touch{ + { + shown = true; + lockCamera = false; + showRotate = true; + showCancel = true; + } + + public void tapped(int x, int y){ + control.input().tryPlaceBlock(x, y, true); + } + }, + none{ + { + delete = true; + shown = true; + both = true; + } + }, + holdDelete{ + { + delete = true; + shown = true; + both = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + Tile tile = world.tile(tilex, tiley); + + if(tile != null && control.input().validBreak(tilex, tiley)){ + if(tile.isLinked()) + tile = tile.getLinked(); + float fin = control.input().breaktime / tile.getBreakTime(); + + if(android && control.input().breaktime > 0){ + Draw.color(Colors.get("breakStart"), Colors.get("break"), fin); + Lines.poly(tile.drawx(), tile.drawy(), 25, 4 + (1f - fin) * 26); + } + Draw.reset(); + } + } + }, + touchDelete{ + { + shown = true; + lockCamera = false; + showRotate = true; + showCancel = true; + delete = true; + } + + public void tapped(int x, int y){ + control.input().tryDeleteBlock(x, y, true); + } + }, + areaDelete{ + int maxlen = 20; + int tilex; + int tiley; + int endx; + int endy; + + { + shown = true; + lockCamera = true; + delete = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + float t = tilesize; + + process(tilex, tiley, endx, endy); + + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + float x = this.tilex * t, y = this.tiley * t, + x2 = this.endx * t, y2 = this.endy * t; + + if(x2 >= x){ + x -= t/2; + x2 += t/2; + } + + if(y2 >= y){ + y -= t/2; + y2 += t/2; + } + + Draw.color(Colors.get("break")); + Lines.stroke(1f); + for(int cx = tilex; cx <= endx; cx ++){ + for(int cy = tiley; cy <= endy; cy ++){ + Tile tile = world.tile(cx, cy); + if(tile != null && tile.getLinked() != null) + tile = tile.getLinked(); + if(tile != null && control.input().validBreak(tile.x, tile.y)){ + Lines.crect(tile.drawx(), tile.drawy(), + tile.block().width * t, tile.block().height * t); + } + } + } + + Lines.stroke(2f); + Draw.color(control.input().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); + Lines.rect(x, y, x2 - x, y2 - y); + Draw.alpha(0.3f); + Draw.crect("blank", x, y, x2 - x, y2 - y); + Draw.reset(); + } + + public void released(int tilex, int tiley, int endx, int endy){ + process(tilex, tiley, endx, endy); + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + + if(android){ + ToolFragment t = ui.toolfrag; + if(!t.confirming || t.px != tilex || t.py != tiley || t.px2 != endx || t.py2 != endy) { + t.confirming = true; + t.px = tilex; + t.py = tiley; + t.px2 = endx; + t.py2 = endy; + return; + } + } + + boolean first = true; + + for(int cx = tilex; cx <= endx; cx ++){ + for(int cy = tiley; cy <= endy; cy ++){ + if(control.input().tryDeleteBlock(cx, cy, first)){ + first = false; + } + } + } + } + + void process(int tilex, int tiley, int endx, int endy){ + + if(Math.abs(endx - tilex) > maxlen){ + endx = Mathf.sign(endx - tilex) * maxlen + tilex; + } + + if(Math.abs(endy - tiley) > maxlen){ + endy = Mathf.sign(endy - tiley) * maxlen + tiley; + } + + if(endx < tilex){ + int t = endx; + endx = tilex; + tilex = t; + } + if(endy < tiley){ + int t = endy; + endy = tiley; + tiley = t; + } + + this.endx = endx; + this.endy = endy; + this.tilex = tilex; + this.tiley = tiley; + } + }, + hold{ + int maxlen = 20; + int tilex; + int tiley; + int endx; + int endy; + int rotation; + + { + lockCamera = true; + shown = true; + showCancel = true; + showRotate = true; + } + + public void draw(int tilex, int tiley, int endx, int endy){ + if(android && !Gdx.input.isTouched(0) && !control.showCursor()){ + return; + } + + float t = tilesize; + Block block = control.input().recipe.result; + Vector2 offset = block.getPlaceOffset(); + + process(tilex, tiley, endx, endy); + int tx = tilex, ty = tiley, ex = endx, ey = endy; + tilex = this.tilex; tiley = this.tiley; + endx = this.endx; endy = this.endy; + float x = this.tilex * t, y = this.tiley * t, + x2 = this.endx * t, y2 = this.endy * t; + + if(x2 >= x){ + x -= block.width * t/2; + x2 += block.width * t/2; + } + + if(y2 >= y){ + y -= block.height * t/2; + y2 += block.height * t/2; + } + + x += offset.x; + y += offset.y; + x2 += offset.x; + y2 += offset.y; + + if(tilex == endx && tiley == endy){ + cursor.draw(tilex, tiley, endx, endy); + }else{ + Lines.stroke(2f); + Draw.color(control.input().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); + Lines.rect(x, y, x2 - x, y2 - y); + Draw.alpha(0.3f); + Draw.crect("blank", x, y, x2 - x, y2 - y); + + Draw.color(Colors.get("placeInvalid")); + + int amount = 1; + for(int cx = 0; cx <= Math.abs(endx - tilex); cx ++){ + for(int cy = 0; cy <= Math.abs(endy - tiley); cy ++){ + int px = tx + cx * Mathf.sign(ex - tx), + py = ty + cy * Mathf.sign(ey - ty); + + renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? rotation * 90 : 0f, px * t + offset.x, py * t + offset.y, px, py); + + if(!control.input().validPlace(px, py, control.input().recipe.result) + || !state.inventory.hasItems(control.input().recipe.requirements, amount)) + Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); + + amount ++; + } + } + + if(control.input().recipe.result.rotate){ + float cx = tx * t, cy = ty * t; + Lines.stroke(2f); + Draw.color(Colors.get("placeRotate")); + tr.trns(rotation * 90, 7, 0); + Lines.line(cx, cy, cx + tr.x, cy + tr.y); + } + Draw.reset(); + } + } + + public void released(int tilex, int tiley, int endx, int endy){ + process(tilex, tiley, endx, endy); + + control.input().rotation = this.rotation; + + boolean first = true; + for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ + for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ + if(control.input().tryPlaceBlock( + tilex + x * Mathf.sign(endx - tilex), + tiley + y * Mathf.sign(endy - tiley), first)){ + first = false; + } + + } + } + } + + void process(int tilex, int tiley, int endx, int endy){ + if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ + endy = tiley; + }else{ + endx = tilex; + } + + if(Math.abs(endx - tilex) > maxlen){ + endx = Mathf.sign(endx - tilex) * maxlen + tilex; + } + + if(Math.abs(endy - tiley) > maxlen){ + endy = Mathf.sign(endy - tiley) * maxlen + tiley; + } + + if(endx > tilex) + rotation = 0; + else if(endx < tilex) + rotation = 2; + else if(endy > tiley) + rotation = 1; + else if(endy < tiley) + rotation = 3; + else + rotation = control.input().rotation; + + if(endx < tilex){ + int t = endx; + endx = tilex; + tilex = t; + } + if(endy < tiley){ + int t = endy; + endy = tiley; + tiley = t; + } + + this.endx = endx; + this.endy = endy; + this.tilex = tilex; + this.tiley = tiley; + } + }; + public boolean lockCamera; + public boolean pan = false; + public boolean shown = false; + public boolean showRotate; + public boolean showCancel; + public boolean delete = false; + public boolean both = false; + + private static final Translator tr = new Translator(); + + public void draw(int tilex, int tiley, int endx, int endy){ + + } + + public void released(int tilex, int tiley, int endx, int endy){ + + } + + public void tapped(int x, int y){ + + } + + @Override + public String toString(){ + return Bundles.get("placemode."+name().toLowerCase()+".name"); + } } \ No newline at end of file From 68593acf89f2374377cae87d4a909097f66a43e2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 15 Apr 2018 16:04:22 -0400 Subject: [PATCH 04/18] Changed UUID generation slightly --- android/src/io/anuke/mindustry/AndroidLauncher.java | 2 ++ core/assets/version.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 6b971c5447..3f9b6bf143 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -115,6 +115,8 @@ public class AndroidLauncher extends AndroidApplication{ + Character.digit(s.charAt(i + 1), 16)); } + if(new String(Base64Coder.encode(data)).equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); + return data; }catch (Exception e){ Settings.defaults("uuid", ""); diff --git a/core/assets/version.properties b/core/assets/version.properties index 68dd48f5aa..97e15ad1ee 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sat Apr 14 21:55:24 EDT 2018 +#Sun Apr 15 15:52:41 EDT 2018 version=release -androidBuildCode=514 +androidBuildCode=516 name=Mindustry code=3.5 build=custom build From 0e50fbf3f2639a3f97571089a55483cf86900152 Mon Sep 17 00:00:00 2001 From: Commodore64x Date: Mon, 16 Apr 2018 09:08:44 +1000 Subject: [PATCH 05/18] Fixed rendering and other issues. --- core/assets/bundles/bundle.properties | 2 +- .../mindustry/graphics/BlockRenderer.java | 19 ++++++++----------- .../io/anuke/mindustry/input/PlaceMode.java | 14 ++++++-------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 72a00fc860..2709ee58da 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -270,7 +270,7 @@ setting.multithread.name=Multithreading setting.fps.name=Show FPS setting.vsync.name=VSync setting.lasers.name=Show Power Lasers -setting.previewopacity.name = Placing Preview Opacity +setting.previewopacity.name=Placing Preview Opacity setting.healthbars.name=Show Entity Health bars setting.pixelate.name=Pixelate Screen setting.musicvol.name=Music Volume diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 4d1b962da1..6939a1e7d2 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.utils.Array; @@ -17,11 +18,11 @@ import io.anuke.mindustry.world.blocks.types.production.Drill; import io.anuke.mindustry.world.blocks.types.production.Pump; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.core.Settings; import io.anuke.ucore.graphics.CacheBatch; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.core.*; import java.util.Arrays; @@ -285,8 +286,7 @@ public class BlockRenderer{ cbatch = new CacheBatch(world.width() * world.height() * 4); } - public void drawPreview(Block block, float drawx, float drawy, float rotation, float opacity) { - Draw.reset(); + public void drawPreview(Block block, float drawx, float drawy, float rotation, float opacity) { Draw.alpha(opacity); Draw.rect(block.name(), drawx, drawy, rotation); } @@ -296,15 +296,17 @@ public class BlockRenderer{ if(control.input().recipe != null && state.inventory.hasItems(control.input().recipe.requirements) && control.input().validPlace(tilex, tiley, block) && (android || control.input().cursorNear())) { - float opacity = (float)Settings.getInt("previewopacity")/100f; - if(block.isMultiblock()) { if((tiley - control.input().getBlockY()) % block.height != 0 || (tilex - control.input().getBlockX()) % block.width != 0) return; } + + float opacity = (float) Settings.getInt("previewopacity") / 100f; + Draw.color(Color.WHITE); + Draw.alpha(opacity); + if(block instanceof Turret) { - Draw.alpha(opacity); if (block.isMultiblock()) { Draw.rect("block-" + block.width + "x" + block.height, drawx, drawy); } else { @@ -314,11 +316,6 @@ public class BlockRenderer{ drawPreview(block, drawx, drawy, rotation, opacity); - Tile tile = world.tile(tilex, tiley); - if((block instanceof Drill || block instanceof Pump) && block.isLayer(tile)) { - block.drawLayer(tile); - } - Draw.reset(); } } diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 3aaf5de822..6bfbf4e57d 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -7,7 +7,6 @@ import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.ui.fragments.ToolFragment; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.production.Drill; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; @@ -35,6 +34,8 @@ public enum PlaceMode{ float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; + renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? control.input().rotation * 90 : 0f, x + offset.x, y + offset.y, tilex, tiley); + Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); Lines.stroke(2f); Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, @@ -42,13 +43,10 @@ public enum PlaceMode{ control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); - renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? control.input().rotation * 90 : 0f, x + offset.x, y + offset.y, tilex, tiley); - if(control.input().recipe.result.rotate){ Draw.color(Colors.get("placeRotate")); tr.trns(control.input().rotation * 90, 7, 0); - Lines.stroke(2f); Lines.line(x, y, x + tr.x, y + tr.y); } } @@ -277,8 +275,6 @@ public enum PlaceMode{ Draw.alpha(0.3f); Draw.crect("blank", x, y, x2 - x, y2 - y); - Draw.color(Colors.get("placeInvalid")); - int amount = 1; for(int cx = 0; cx <= Math.abs(endx - tilex); cx ++){ for(int cy = 0; cy <= Math.abs(endy - tiley); cy ++){ @@ -288,9 +284,11 @@ public enum PlaceMode{ renderer.getBlocks().handlePreview(control.input().recipe.result, control.input().recipe.result.rotate ? rotation * 90 : 0f, px * t + offset.x, py * t + offset.y, px, py); if(!control.input().validPlace(px, py, control.input().recipe.result) - || !state.inventory.hasItems(control.input().recipe.requirements, amount)) + || !state.inventory.hasItems(control.input().recipe.requirements, amount)){ + Lines.stroke(2f); + Draw.color(Colors.get("placeInvalid")); Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); - + } amount ++; } } From e6f9ce888ff059f81e7262219180bf2dd2610ed4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 15 Apr 2018 23:12:26 -0400 Subject: [PATCH 06/18] Fixed autosave not updating meta --- core/assets/version.properties | 4 ++-- core/src/io/anuke/mindustry/io/Saves.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/assets/version.properties b/core/assets/version.properties index 97e15ad1ee..327edb9062 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sun Apr 15 15:52:41 EDT 2018 +#Sun Apr 15 23:12:17 EDT 2018 version=release -androidBuildCode=516 +androidBuildCode=517 name=Mindustry code=3.5 build=custom build diff --git a/core/src/io/anuke/mindustry/io/Saves.java b/core/src/io/anuke/mindustry/io/Saves.java index 95bb189d08..89b07667b7 100644 --- a/core/src/io/anuke/mindustry/io/Saves.java +++ b/core/src/io/anuke/mindustry/io/Saves.java @@ -52,6 +52,7 @@ public class Saves { exec.submit(() -> { SaveIO.saveToSlot(current.index); + current.meta = SaveIO.getData(current.index); saving = false; return true; }); From e21d92cf4dafb0d20a9b592ecce66a10b4455e82 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 16 Apr 2018 09:58:31 -0400 Subject: [PATCH 07/18] Changed UUID algorithm on desktop --- .../mindustry/desktop/DesktopPlatform.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 92065eb60c..422a466a2d 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -3,12 +3,14 @@ package io.anuke.mindustry.desktop; import club.minnced.discord.rpc.DiscordEventHandlers; import club.minnced.discord.rpc.DiscordRPC; import club.minnced.discord.rpc.DiscordRichPresence; +import com.badlogic.gdx.utils.Base64Coder; import io.anuke.kryonet.DefaultThreadImpl; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.ThreadHandler.ThreadProvider; import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.net.Net; import io.anuke.ucore.UCore; +import io.anuke.ucore.core.Settings; import io.anuke.ucore.util.Strings; import javax.swing.*; @@ -19,6 +21,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Locale; +import java.util.Random; import static io.anuke.mindustry.Vars.*; @@ -106,15 +109,34 @@ public class DesktopPlatform extends Platform { try { Enumeration e = NetworkInterface.getNetworkInterfaces(); NetworkInterface out; - for(out = e.nextElement(); out.getHardwareAddress() == null && e.hasMoreElements(); out = e.nextElement()); + for(out = e.nextElement(); out.getHardwareAddress() == null && e.hasMoreElements() && validAddress(out.getHardwareAddress()); out = e.nextElement()); byte[] bytes = out.getHardwareAddress(); byte[] result = new byte[8]; System.arraycopy(bytes, 0, result, 0, bytes.length); + + if(new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); + return result; }catch (Exception e){ - e.printStackTrace(); - return null; + Settings.defaults("uuid", ""); + + String uuid = Settings.getString("uuid"); + if(uuid.isEmpty()){ + byte[] result = new byte[8]; + new Random().nextBytes(result); + uuid = new String(Base64Coder.encode(result)); + Settings.putString("uuid", uuid); + Settings.save(); + return result; + } + return Base64Coder.decode(uuid); } } + + private boolean validAddress(byte[] bytes){ + byte[] result = new byte[8]; + System.arraycopy(bytes, 0, result, 0, bytes.length); + return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA="); + } } From d396149521f6a488c02b8e5d63e78a8299fe3ea9 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 16 Apr 2018 20:28:47 -0400 Subject: [PATCH 08/18] Implemented passing of commands as arguments --- .../mindustry/server/MindustryServer.java | 7 ++++++- .../anuke/mindustry/server/ServerControl.java | 19 ++++++++++++++++++- .../mindustry/server/ServerLauncher.java | 5 ++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/server/src/io/anuke/mindustry/server/MindustryServer.java b/server/src/io/anuke/mindustry/server/MindustryServer.java index 8ab8e82e0c..945683f14a 100644 --- a/server/src/io/anuke/mindustry/server/MindustryServer.java +++ b/server/src/io/anuke/mindustry/server/MindustryServer.java @@ -11,6 +11,11 @@ import io.anuke.ucore.modules.ModuleCore; import static io.anuke.mindustry.Vars.*; public class MindustryServer extends ModuleCore { + private String[] args; + + public MindustryServer(String[] args){ + this.args = args; + } @Override public void init(){ @@ -23,6 +28,6 @@ public class MindustryServer extends ModuleCore { module(world = new World()); module(netServer = new NetServer()); module(netCommon = new NetCommon()); - module(new ServerControl()); + module(new ServerControl(args)); } } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index e93565c507..afb2e32963 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -41,7 +41,7 @@ public class ServerControl extends Module { private final CommandHandler handler = new CommandHandler(""); private ShuffleMode mode; - public ServerControl(){ + public ServerControl(String[] args){ Settings.defaultList( "shufflemode", "normal", "bans", "", @@ -69,7 +69,24 @@ public class ServerControl extends Module { @Override public void debug(String tag, String message, Throwable exception) { } }); + String[] commands = {}; + + if(args.length > 0){ + commands = String.join(" ", args).split(","); + Log.info("&lmFound {0} command-line arguments to parse. {1}", commands.length); + } + registerCommands(); + + for(String s : commands){ + Response response = handler.handleMessage(s); + if(response.type != ResponseType.valid){ + Log.err("Invalid command argument sent: '{0}': {1}", s, response.type.name()); + Log.err("Argument usage: &lc , "); + System.exit(1); + } + } + Thread thread = new Thread(this::readCommands, "Server Controls"); thread.setDaemon(true); thread.start(); diff --git a/server/src/io/anuke/mindustry/server/ServerLauncher.java b/server/src/io/anuke/mindustry/server/ServerLauncher.java index 16a7e9ea0c..1abd040a47 100644 --- a/server/src/io/anuke/mindustry/server/ServerLauncher.java +++ b/server/src/io/anuke/mindustry/server/ServerLauncher.java @@ -7,12 +7,12 @@ import io.anuke.mindustry.net.Net; public class ServerLauncher{ - public static void main(String[] args) throws Exception{ + public static void main(String[] args){ Net.setClientProvider(new KryoClient()); Net.setServerProvider(new KryoServer()); - new HeadlessApplication(new MindustryServer()); + new HeadlessApplication(new MindustryServer(args)); //find and handle uncaught exceptions in libGDX thread for(Thread thread : Thread.getAllStackTraces().keySet()){ @@ -24,6 +24,5 @@ public class ServerLauncher{ break; } } - } } \ No newline at end of file From ee24eb8d1b56c07ec106f3981147478ad9a05fa0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 16 Apr 2018 21:11:49 -0400 Subject: [PATCH 09/18] Made saves load backup files if original save gets corrupted --- core/assets/version.properties | 4 ++-- core/src/io/anuke/mindustry/io/SaveIO.java | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/assets/version.properties b/core/assets/version.properties index 327edb9062..4879e0b49a 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sun Apr 15 23:12:17 EDT 2018 +#Mon Apr 16 21:11:17 EDT 2018 version=release -androidBuildCode=517 +androidBuildCode=519 name=Mindustry code=3.5 build=custom build diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 662f71ea7c..0a150d675a 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -130,7 +130,15 @@ public class SaveIO{ } public static void load(FileHandle file){ - load(file.read()); + try { + load(file.read()); + }catch (RuntimeException e){ + e.printStackTrace(); + FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); + if(backup.exists()){ + load(backup.read()); + } + } } public static void load(InputStream is){ From 714c5fd7840dbf188a1cfced287ac36384d72221 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 17 Apr 2018 08:59:01 -0400 Subject: [PATCH 10/18] Added missing synchronized block --- .../mindustry/entities/effect/TeslaOrb.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java b/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java index eb35433236..40b860a01c 100644 --- a/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java +++ b/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java @@ -45,15 +45,18 @@ public class TeslaOrb extends Entity{ } Array enemies = Entities.getNearby(enemyGroup, curx, cury, range*2f); - - for(SolidEntity entity : enemies){ - if(entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((Enemy)entity)){ - hit.add((Enemy)entity); - points.add(new Vector2(entity.x + Mathf.range(shake), entity.y + Mathf.range(shake))); - damageEnemy((Enemy)entity); - curx = entity.x; - cury = entity.y; - break; + + synchronized (Entities.entityLock) { + + for (SolidEntity entity : enemies) { + if (entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((Enemy) entity)) { + hit.add((Enemy) entity); + points.add(new Vector2(entity.x + Mathf.range(shake), entity.y + Mathf.range(shake))); + damageEnemy((Enemy) entity); + curx = entity.x; + cury = entity.y; + break; + } } } } From 8cef351ed9f09176ff222d76089e7f0d1f70643e Mon Sep 17 00:00:00 2001 From: Commodore64x Date: Sat, 21 Apr 2018 12:44:23 +1000 Subject: [PATCH 11/18] Fixed preview for multiblocks. --- .../mindustry/graphics/BlockRenderer.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 6939a1e7d2..967449dfff 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.utils.Array; @@ -14,8 +13,6 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.StaticBlock; import io.anuke.mindustry.world.blocks.types.defense.Turret; -import io.anuke.mindustry.world.blocks.types.production.Drill; -import io.anuke.mindustry.world.blocks.types.production.Pump; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Settings; @@ -23,7 +20,6 @@ import io.anuke.ucore.graphics.CacheBatch; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; - import java.util.Arrays; import static io.anuke.mindustry.Vars.*; @@ -32,6 +28,8 @@ import static io.anuke.ucore.core.Core.camera; public class BlockRenderer{ private final static int chunksize = 32; private final static int initialRequests = 32*32; + private static float storeX = 0; + private static float storeY = 0; private int[][][] cache; private CacheBatch cbatch; @@ -296,11 +294,22 @@ public class BlockRenderer{ if(control.input().recipe != null && state.inventory.hasItems(control.input().recipe.requirements) && control.input().validPlace(tilex, tiley, block) && (android || control.input().cursorNear())) { - if(block.isMultiblock()) { - if((tiley - control.input().getBlockY()) % block.height != 0 - || (tilex - control.input().getBlockX()) % block.width != 0) return; - } - + if(block.isMultiblock()) { + float halfBlockWidth = (block.width * tilesize) / 2; + float halfBlockHeight = (block.height * tilesize) / 2; + if((storeX == 0 && storeY == 0)) { + storeX = drawx; + storeY = drawy; + } + if((storeX == drawx - halfBlockWidth || storeX == drawx + halfBlockWidth || storeY == drawy - halfBlockHeight || storeY == drawy + halfBlockHeight) && + ((tiley - control.input().getBlockY()) % block.height != 0 || (tilex - control.input().getBlockX()) % block.width != 0)) { + return; + } + else { + storeX = drawx; + storeY = drawy; + } + } float opacity = (float) Settings.getInt("previewopacity") / 100f; Draw.color(Color.WHITE); From 8a965e56cd78c9d0807f573246315b1148b7acd0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 21 Apr 2018 11:02:54 -0400 Subject: [PATCH 12/18] Fixed not being able to pan with invalid recipe selected --- build.gradle | 2 +- core/assets/version.properties | 4 ++-- core/src/io/anuke/mindustry/input/GestureHandler.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 7e925de460..5e967407bc 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ project(":core") { apply plugin: "java" dependencies { - boolean comp = System.properties["release"] == null || System.properties["release"].equals("false") + boolean comp = false if(!comp){ println("NOTICE: Compiling release build.") diff --git a/core/assets/version.properties b/core/assets/version.properties index 4879e0b49a..a2312de7d6 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Mon Apr 16 21:11:17 EDT 2018 +#Sat Apr 21 01:15:29 EDT 2018 version=release -androidBuildCode=519 +androidBuildCode=523 name=Mindustry code=3.5 build=custom build diff --git a/core/src/io/anuke/mindustry/input/GestureHandler.java b/core/src/io/anuke/mindustry/input/GestureHandler.java index dc1fbdbfca..2eecb54ac6 100644 --- a/core/src/io/anuke/mindustry/input/GestureHandler.java +++ b/core/src/io/anuke/mindustry/input/GestureHandler.java @@ -47,7 +47,7 @@ public class GestureHandler extends GestureAdapter{ if(control.showCursor() && !Inputs.keyDown("select")) return false; if(!control.showCursor() && !(control.input().recipe != null - && control.input().placeMode.lockCamera) && + && control.input().placeMode.lockCamera && state.inventory.hasItems(control.input().recipe.requirements)) && !(control.input().recipe == null && control.input().breakMode.lockCamera)){ float dx = deltaX*Core.camera.zoom/Core.cameraScale, dy = deltaY*Core.camera.zoom/Core.cameraScale; player.x -= dx; From 97360b33f41f2331e213377da47fbb6332114605 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 21 Apr 2018 15:18:12 -0400 Subject: [PATCH 13/18] Added new chain/titan sprites --- .../sprites/blocks/chainturret-icon.png | Bin 281 -> 281 bytes .../sprites/blocks/chainturret-icon_old.png | Bin 0 -> 281 bytes .../assets-raw/sprites/blocks/chainturret.png | Bin 514 -> 402 bytes .../sprites/blocks/chainturret_old.png | Bin 0 -> 514 bytes .../sprites/blocks/titancannon-icon.png | Bin 250 -> 256 bytes .../sprites/blocks/titancannon-icon_old.png | Bin 0 -> 250 bytes .../assets-raw/sprites/blocks/titancannon.png | Bin 603 -> 532 bytes .../sprites/blocks/titancannon_old.png | Bin 0 -> 603 bytes core/assets/sprites/sprites.atlas | 610 +++++++++--------- core/assets/sprites/sprites.png | Bin 92976 -> 94754 bytes core/assets/version.properties | 4 +- 11 files changed, 321 insertions(+), 293 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/chainturret-icon_old.png create mode 100644 core/assets-raw/sprites/blocks/chainturret_old.png create mode 100644 core/assets-raw/sprites/blocks/titancannon-icon_old.png create mode 100644 core/assets-raw/sprites/blocks/titancannon_old.png diff --git a/core/assets-raw/sprites/blocks/chainturret-icon.png b/core/assets-raw/sprites/blocks/chainturret-icon.png index 79f76d7ebae4a7334fd50b27eae7774ddcd1842e..e18f11a28e5e9ce324466c6823ef7184c0c775cc 100644 GIT binary patch delta 183 zcmbQqG?Qt9J=Y@^QDI(ogRRe-Cwl7F_f9b6Y7P)^ng1w1S4X$$-V^h>0WKVsfn9Nik7Au?lq^`ex*lLcnH>t31l2p`QqzAmP~jJxU9 pY^4i^Y%flwey=^{nlAs3NgyWDlGE~F3IhWJgQu&X%Q~loCIA9NO|1X` delta 183 zcmbQqG?Qt9J=a5SZWawIU03eliJtoP$u(QoKC)*vd~kJJ*Z=?j>;C-z|Ni*@A2)n> zczAfe%kN7~NJvPy@$D*S9zzfB-iQe%}g_)U|xmnyiB(Y|K zWfu$2fg|zn@304U@FavSWEL?$#y<1#Tt;JFwc|gsqL0?kIQ+IJR6^uw>qD-Dci$e} qV^=b~crJo9{lmd05}mvS49)T}*FC4coy5Svz~JfX=d#Wzp$Pz6z)+6> diff --git a/core/assets-raw/sprites/blocks/chainturret-icon_old.png b/core/assets-raw/sprites/blocks/chainturret-icon_old.png new file mode 100644 index 0000000000000000000000000000000000000000..12e4f5f7d571fe3b8e0016bc30b4b9b13e505980 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0y~yU;weXIM^5%7w#! z_P`FFgs_FoBId`~XC9u*Xw0j2{6|*w(fS#O-}Zz`h&*k5$d&N!+oOBzh8NF8u%>@F g_(Yt~p$*SgBWwWw- zZsxsx;fdJFjEoiEc{)zW=6bDolXOy1scU+Y`0*M2MpJFi*gWfHWWVy3Od%IrqU^d- z3QvY-gkz2Vtik#^ZXoy;;#zvfH{nzF4t$m?Rymc7BZ?wze&SZTL0-~8T(^b*rW zU1}!jd6Qy77!(XvpV5CD%E-{|-S&`+Va1|M^OZl%V&vtl8N0pRY(2_23r;C4HF48i z`tZm3c0*={+pm}zUg<@C$X_4-%-!sKUso)L?BkyJrziG4WYJi8m4ShQ!PC{xWt~$( F696IIl*<4B delta 461 zcmbQl+{7}$zWyOMH;aar!6#{R1_lPn64!_l=ltB<)VvY~=c3falGGH1^30M91$R&1 zfbd2>aRvs)8c!F;5R22bllAkN90iWnS1(LIr5PgX9@NOj=xXvr#n*T8D=Qg!#cm%?C zAG!L@bG}<6_l1_b&uZ$=Ol(^JUY_C45o5F3Yx|U0_wL>+nV_(prKnoOV&0m6?3xRM z=dAv|L#;2WqB2WH;M2D~UERhOsz2ZGY^m|Bs?3^Ew&^PKPTLCY);CAAp9(!bd5Yy} z=gqJ$X*vxLk59dEmd)*?WybwHGlTl08WBr;FV5l(`LKP{8?`T%6Qa9jhr5Yo20K*U zXqqDQ%J<^VdD?q_=S({H^^VA-phvs(`W`F%`uopw=ic3WPu**m4_A_Zyi0HY_UdiQ VyDLiOFfcGMc)I$ztaD0e0s!a|&`AIQ diff --git a/core/assets-raw/sprites/blocks/chainturret_old.png b/core/assets-raw/sprites/blocks/chainturret_old.png new file mode 100644 index 0000000000000000000000000000000000000000..3b03c296f1ce66b3a1b06a3f9a5b2af543524e05 GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7I14-?iy0WWg+Z8+Vb&Z8 z1_lQ95>H=O_J`cuEE-w{pQOzh7#Ji=Tq8=H^K)}k^GX<;i&7IyQd1PlGfOfQ+&z5* z!W;R-85kIAJY5_^EKb)>*3V~h6gXO6y)gZhW{9YJP$L_otH~1;U*E~EtYqXF&$1sd zbzCs}!44MZS;8Vm7I}JITCEmZp3b+?^zPfjKb2YKY4^^|o*8Q>)mtFL&TxBM=1p(b z4|3O8B)4>Dvu^O1t>hcbFmHMA8UvorMH~&&_J-6w5)9wnw%}yp*6#Tg%NP#aKFloU zAkns^JNv1+-1o21!KPhGlVu+4tLvU$!G2QLZ$XeAO0T*ZjIa*TJAopIWw_o{d;+aKSzwsYOn26X5G7cuVjM4c9x=Q5sP_i{;_K=44$+4 z`wq3fsEW!g8G%pV_H=a{Td4kg!?UHvx2iI0M%kvT%sXu>v|HaC(S9oQ_~a>;r=2&$ zzNG0iJUl-2##uJEla?9x^UMtDk7`6L@x3^UH{`?iO>fk`SWbxUnjJ2d8SGGXqiKrJ zE8mMd=V|Z#oipj&*E=GUf*$SC>wB#5>+e6$oqKohJ$0{LK3qxu@h-jn+pD)J@2)7B R!@$76;OXk;vd$@?2>|>4){X!G literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/blocks/titancannon-icon.png b/core/assets-raw/sprites/blocks/titancannon-icon.png index 29b3d2cb14db827a91a1ff7a2bc7ce3be1deb633..718e833971c1883290a840524a711eee5254a0d3 100644 GIT binary patch delta 165 zcmeyx*uXTwp6d~ds4%ZkYzA}2L{E+SDo+>35Q)plf9h?Y+cO(J`2Tgz|8>=J|Nqz9 zKL7uJzkHzKBpKnD_9$&;W@hHYf7|mV-`Ur6D;+y<;J|?+2M!!C2!3hqC!JVSAe^{N z;}o~C#wqT_9S231-A_I`p12Yj5;lQoX8Kj50U)_wc5#>U3Ri8mP78D@rh Xt`^WtpZJV{fq}u()z4*}Q$iB}f7nOz delta 159 zcmZo*`o%cGp6ekuH;X2lw4vM7iJltuC7v#hArhC9YqqX^WX~+v(AwD8n0Px}olXB; zEzhENQ#B^7FW+|f>5POX1K02J`%-uO|Df9?!OYC;vT*K3EWg4frjWtej zFYY)fDrZ&A?#y(o?WCb%G_x`1+}?!(@(tQ9+vM&>v9YnSxg{~nFr3(6RDQ5Bvw(qt Pi-Ez@)z4*}Q$iB}E0;Qa diff --git a/core/assets-raw/sprites/blocks/titancannon-icon_old.png b/core/assets-raw/sprites/blocks/titancannon-icon_old.png new file mode 100644 index 0000000000000000000000000000000000000000..9d4cee27fbb8d683b1c859e8eb4f68bc3f8bd988 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0y~yU;weXIM^5%7Y=C<=YNFosrOF z;QC#DU+RwkA9TAUn3E$Gq^gu?%Mdylv&#WdnCE*86X;-gaf9Eqj;?lZ%S@u;%299m7^CZ^o zRx~|-GKXu&%=hxiJPZe(Csm5<{Cia5$IDHdijD6_7cf}FhDp?SFFDcpxiU2LV&R#x zD~$f#?~kyvGwi8RnJc3CK_kFV$ZwHgL4jtfkn!@_Ay58KP`YM%OhS6wTZO34$5N7e zI?JYhkljEk6IlsifVYb(VIW#2El$nm1YhWFoG z1%r6^z#{d{GU7jTrz;(hF%)A^nC2e1zFK3cOhDX=5b?r-WS%KOE3WU|dvjdv^-JnYc>*8Y)KvN?N|^R*x*1_lNOPgg&ebxsLQ0O--$^8f$< delta 551 zcmbQja+_s>ef>jjZWawA<$2AC3=9mCC9V-A&iT2ysd*&~&PAz-C8;S2<(VZJ3hti1 z0pX2&;tULoS3O-ELp+Wz4O7f-b`bfePAO+| zk1L9_nHk<4Jzsu(W8j@r$BY?j_Vj+7n}0RSeHmBWPsMkwN5h_4nZ+DW)7~o{7W*@C zv2rl$b;d7|>yn*S4X?J;|JM^e{N|Ry?27uXOwO)o&Q;Eno_(@DyU@_Ee%4{3H~r7! z#g>RIU3)p*v_ENsnP_P4^fZbx~bfU$MOVSI3>(uAZ~9wJ&$BDO)vZR?JbWN!yM#Zf2?9+^O!_ zl2GFFs^Z)6%`DGNWD3>^Y!j9)*}SaqmEElMqLDcZrUr_4`h{k1R_0oCCW7zru|F$k z%<0}SN9F8BnPZ=p82{$*_@Bmj>-eI*F8F8vH&^z|#( zbuyO;?BHt34H616z4%~7TGGzjw?FcoDC4SlzwiCt@3l|PMd*mVh-#nyT#BJd!+6K{ zZK+!XbIhdIxLx1%$(f;{^d=+2i)!)Cn_@A&>%P7;oc?~QyjKB(h3&IV(s!i_9#<4; zGc&w9dcOSn#=twLju|u5?CJeDH~(su`!cS$pNj8VkA^+9GK)E$roC4@EcR#OV&!1g z>x^F_*Cjiv8eVPruP1u=%`Jo374==2oL$kJtDGl2`(%A~p`l^@tiwWY`k%*(EfHI~ z_Hw#uf6@js(a_xM!6Ms*JZE`3WCdT}IB|((nlS&mWb=ltEVsXI+5UoQ&b#1FpTvuo zlh=v*u8q0sqPn!cVtMzkjytzqJ!fTWU+!E}wrbL>n4?ycwjFKU%(A&t-Loa3#OGDT zx8s{xo}0)NtP|KKEM2mBS>Y?YS?fh3a~4bu6z}v4&EBlcwdhO)-{WI{R?e8yy-FD_oN_KR3lFT`Bf{ZSm9uF(*Sn}ia;-5vyAx{|UtQ3P{q~-39RmXcgQu&X%Q~lo FCIA?!1%3bk literal 0 HcmV?d00001 diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 472d9352cd..1b4eb5e605 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -13,63 +13,63 @@ background index: -1 blank rotate: false - xy: 424, 195 + xy: 791, 491 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 blackrock1 rotate: false - xy: 565, 274 + xy: 79, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackrockshadow1 rotate: false - xy: 79, 48 + xy: 1014, 487 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone1 rotate: false - xy: 693, 326 + xy: 615, 278 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone2 rotate: false - xy: 695, 410 + xy: 615, 268 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstone3 rotate: false - xy: 695, 400 + xy: 768, 436 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock1 rotate: false - xy: 141, 88 + xy: 780, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock2 rotate: false - xy: 151, 88 + xy: 772, 426 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blackstoneblock3 rotate: false - xy: 161, 88 + xy: 778, 436 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -83,14 +83,14 @@ blackstoneedge index: -1 block rotate: false - xy: 159, 78 + xy: 85, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 block-2x2 rotate: false - xy: 791, 495 + xy: 473, 227 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -104,14 +104,14 @@ block-3x3 index: -1 block-middle rotate: false - xy: 603, 278 + xy: 190, 112 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 chainturret rotate: false - xy: 473, 227 + xy: 342, 157 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -123,114 +123,128 @@ chainturret-icon orig: 10, 10 offset: 0, 0 index: -1 +chainturret-icon_old + rotate: false + xy: 651, 382 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +chainturret_old + rotate: false + xy: 362, 177 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 coal1 rotate: false - xy: 643, 275 + xy: 153, 70 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal2 rotate: false - xy: 768, 448 + xy: 85, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coal3 rotate: false - xy: 778, 449 + xy: 89, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coaldrill rotate: false - xy: 768, 438 + xy: 790, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coalgenerator rotate: false - xy: 778, 439 + xy: 788, 439 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coalgenerator-top rotate: false - xy: 788, 449 + xy: 800, 452 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 coalpurifier rotate: false - xy: 788, 439 + xy: 810, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 combustiongenerator rotate: false - xy: 798, 453 + xy: 820, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 compositewall rotate: false - xy: 798, 443 + xy: 830, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduit rotate: false - xy: 808, 453 + xy: 840, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduitbottom rotate: false - xy: 808, 443 + xy: 850, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduitliquid rotate: false - xy: 818, 453 + xy: 860, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conduittop rotate: false - xy: 818, 443 + xy: 95, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyor rotate: false - xy: 828, 453 + xy: 99, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyormove rotate: false - xy: 828, 443 + xy: 95, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 conveyortunnel rotate: false - xy: 838, 453 + xy: 870, 453 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -244,42 +258,42 @@ core index: -1 cross rotate: false - xy: 838, 443 + xy: 880, 455 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 crucible rotate: false - xy: 848, 453 + xy: 105, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 deepwater rotate: false - xy: 858, 455 + xy: 109, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt1 rotate: false - xy: 848, 443 + xy: 105, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt2 rotate: false - xy: 858, 445 + xy: 115, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 dirt3 rotate: false - xy: 1014, 475 + xy: 119, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -293,119 +307,119 @@ dirtedge index: -1 door rotate: false - xy: 73, 26 + xy: 115, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 door-large rotate: false - xy: 809, 495 + xy: 491, 227 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 door-large-icon rotate: false - xy: 85, 38 + xy: 125, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 door-large-open rotate: false - xy: 491, 227 + xy: 380, 177 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 door-open rotate: false - xy: 557, 199 + xy: 129, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 doubleturret rotate: false - xy: 663, 382 + xy: 675, 382 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 duriumwall rotate: false - xy: 653, 275 + xy: 125, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 duriumwall-large rotate: false - xy: 379, 177 + xy: 828, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 duriumwall-large-icon rotate: false - xy: 798, 433 + xy: 135, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 enemyspawn rotate: false - xy: 808, 433 + xy: 145, 58 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 flameturret rotate: false - xy: 675, 382 + xy: 669, 370 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 fluxpump rotate: false - xy: 818, 433 + xy: 139, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass1 rotate: false - xy: 828, 433 + xy: 135, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass2 rotate: false - xy: 838, 433 + xy: 155, 60 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grass3 rotate: false - xy: 848, 433 + xy: 149, 48 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassblock1 rotate: false - xy: 858, 435 + xy: 145, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 grassblock2 rotate: false - xy: 868, 455 + xy: 159, 50 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -419,112 +433,112 @@ grassedge index: -1 ice1 rotate: false - xy: 868, 445 + xy: 155, 38 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice2 rotate: false - xy: 868, 435 + xy: 432, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ice3 rotate: false - xy: 872, 465 + xy: 442, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iceedge rotate: false - xy: 674, 426 + xy: 328, 129 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 icerock1 rotate: false - xy: 878, 455 + xy: 792, 429 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerock2 rotate: false - xy: 878, 445 + xy: 798, 439 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow1 rotate: false - xy: 878, 435 + xy: 802, 429 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow1 rotate: false - xy: 878, 435 + xy: 802, 429 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icerockshadow2 rotate: false - xy: 882, 465 + xy: 450, 214 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rockshadow2 rotate: false - xy: 882, 465 + xy: 450, 214 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron1 rotate: false - xy: 908, 455 + xy: 462, 174 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron2 rotate: false - xy: 908, 445 + xy: 792, 419 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 iron3 rotate: false - xy: 908, 435 + xy: 802, 419 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 irondrill rotate: false - xy: 912, 465 + xy: 470, 215 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 ironwall rotate: false - xy: 918, 455 + xy: 470, 205 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 junction rotate: false - xy: 918, 445 + xy: 470, 195 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -538,42 +552,42 @@ laserturret index: -1 lava rotate: false - xy: 918, 435 + xy: 468, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 lavaedge rotate: false - xy: 858, 465 + xy: 874, 465 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 lavasmelter rotate: false - xy: 922, 465 + xy: 480, 217 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquiditemjunction rotate: false - xy: 928, 455 + xy: 480, 207 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidjunction rotate: false - xy: 928, 445 + xy: 490, 217 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 liquidrouter rotate: false - xy: 928, 435 + xy: 480, 197 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -587,28 +601,28 @@ machineturret index: -1 megarepairturret rotate: false - xy: 189, 110 + xy: 683, 414 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 mortarturret rotate: false - xy: 189, 98 + xy: 683, 402 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 mossblock rotate: false - xy: 932, 465 + xy: 490, 207 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 mossstone rotate: false - xy: 932, 465 + xy: 490, 207 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -629,7 +643,7 @@ nuclearreactor-center index: -1 nuclearreactor-icon rotate: false - xy: 938, 455 + xy: 490, 197 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -643,448 +657,448 @@ nuclearreactor-lights index: -1 nuclearreactor-small rotate: false - xy: 87, 94 + xy: 87, 76 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 oil rotate: false - xy: 938, 445 + xy: 472, 175 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 oiledge rotate: false - xy: 902, 481 + xy: 918, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 oilrefinery rotate: false - xy: 938, 435 + xy: 478, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 omnidrill rotate: false - xy: 942, 465 + xy: 488, 187 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 plasmaturret rotate: false - xy: 189, 86 + xy: 141, 68 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 playerspawn rotate: false - xy: 948, 455 + xy: 482, 175 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powerbooster rotate: false - xy: 948, 445 + xy: 492, 177 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 poweredconveyor rotate: false - xy: 948, 435 + xy: 498, 187 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 poweredconveyormove rotate: false - xy: 952, 465 + xy: 502, 177 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powerlaser rotate: false - xy: 958, 455 + xy: 358, 147 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powerlasercorner rotate: false - xy: 958, 445 + xy: 358, 137 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 powerlaserrouter rotate: false - xy: 958, 435 + xy: 358, 127 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulseconduit rotate: false - xy: 962, 465 + xy: 688, 438 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulseconduitbottom rotate: false - xy: 968, 455 + xy: 688, 428 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pulseconduittop rotate: false - xy: 968, 445 + xy: 657, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 pump rotate: false - xy: 968, 435 + xy: 567, 262 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 repairturret rotate: false - xy: 336, 148 + xy: 603, 276 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 rock1 rotate: false - xy: 972, 465 + xy: 577, 262 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rock2 rotate: false - xy: 978, 455 + xy: 587, 262 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 router rotate: false - xy: 978, 445 + xy: 569, 252 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rtgenerator rotate: false - xy: 978, 435 + xy: 569, 242 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 rtgenerator-top rotate: false - xy: 982, 465 + xy: 579, 252 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand1 rotate: false - xy: 988, 455 + xy: 569, 232 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand2 rotate: false - xy: 988, 445 + xy: 579, 242 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sand3 rotate: false - xy: 988, 435 + xy: 569, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock1 rotate: false - xy: 992, 465 + xy: 579, 232 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock2 rotate: false - xy: 998, 455 + xy: 569, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandblock3 rotate: false - xy: 998, 445 + xy: 579, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sandedge rotate: false - xy: 916, 481 + xy: 932, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shadow rotate: false - xy: 348, 148 + xy: 625, 273 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 shieldgenerator rotate: false - xy: 1002, 465 + xy: 589, 252 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shotgunturret rotate: false - xy: 690, 384 + xy: 637, 273 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 shrub rotate: false - xy: 431, 172 + xy: 597, 262 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shrubshadow rotate: false - xy: 441, 172 + xy: 599, 252 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 smelter rotate: false - xy: 201, 109 + xy: 599, 242 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 smelter-middle rotate: false - xy: 201, 99 + xy: 599, 232 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 sniperturret rotate: false - xy: 693, 372 + xy: 649, 273 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 snow1 rotate: false - xy: 211, 109 + xy: 599, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow2 rotate: false - xy: 201, 89 + xy: 599, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snow3 rotate: false - xy: 211, 99 + xy: 569, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock1 rotate: false - xy: 221, 109 + xy: 579, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock2 rotate: false - xy: 211, 89 + xy: 589, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowblock3 rotate: false - xy: 221, 99 + xy: 599, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 snowedge rotate: false - xy: 944, 481 + xy: 960, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 sorter rotate: false - xy: 231, 109 + xy: 65, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelconveyor rotate: false - xy: 221, 89 + xy: 75, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelconveyormove rotate: false - xy: 231, 99 + xy: 69, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelwall rotate: false - xy: 241, 109 + xy: 79, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 steelwall-large rotate: false - xy: 105, 112 + xy: 105, 94 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 steelwall-large-icon rotate: false - xy: 231, 89 + xy: 83, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone1 rotate: false - xy: 241, 99 + xy: 85, 16 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone2 rotate: false - xy: 241, 89 + xy: 93, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stone3 rotate: false - xy: 251, 101 + xy: 103, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock1 rotate: false - xy: 251, 91 + xy: 113, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock2 rotate: false - xy: 261, 101 + xy: 123, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneblock3 rotate: false - xy: 261, 91 + xy: 133, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stonedrill rotate: false - xy: 271, 101 + xy: 143, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stoneedge rotate: false - xy: 986, 481 + xy: 674, 426 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 stoneformer rotate: false - xy: 271, 91 + xy: 153, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 stonewall rotate: false - xy: 281, 101 + xy: 95, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 teleporter rotate: false - xy: 281, 91 + xy: 105, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 teleporter-top rotate: false - xy: 291, 101 + xy: 115, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 thermalgenerator rotate: false - xy: 291, 91 + xy: 125, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1098,147 +1112,161 @@ titancannon index: -1 titancannon-icon rotate: false - xy: 693, 360 + xy: 625, 261 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +titancannon-icon_old + rotate: false + xy: 637, 261 + size: 10, 10 + orig: 10, 10 + offset: 0, 0 + index: -1 +titancannon_old + rotate: false + xy: 316, 143 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 titanium1 rotate: false - xy: 301, 101 + xy: 135, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium2 rotate: false - xy: 301, 91 + xy: 145, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanium3 rotate: false - xy: 311, 101 + xy: 155, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumdrill rotate: false - xy: 311, 91 + xy: 89, 6 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumpurifier rotate: false - xy: 321, 101 + xy: 99, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumshieldwall rotate: false - xy: 321, 91 + xy: 109, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumwall rotate: false - xy: 331, 101 + xy: 119, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titaniumwall-large rotate: false - xy: 105, 76 + xy: 141, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titaniumwall-large-icon rotate: false - xy: 331, 91 + xy: 129, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 turret rotate: false - xy: 693, 348 + xy: 649, 261 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 uranium1 rotate: false - xy: 388, 167 + xy: 163, 28 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 uranium2 rotate: false - xy: 398, 167 + xy: 165, 18 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 uranium3 rotate: false - xy: 408, 167 + xy: 169, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 uraniumdrill rotate: false - xy: 418, 169 + xy: 190, 102 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 water rotate: false - xy: 211, 79 + xy: 220, 109 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 wateredge rotate: false - xy: 1000, 481 + xy: 722, 428 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 waveturret rotate: false - xy: 693, 336 + xy: 768, 446 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 weaponfactory rotate: false - xy: 123, 94 + xy: 123, 76 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 weaponfactory-icon rotate: false - xy: 221, 79 + xy: 230, 109 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bullet rotate: false - xy: 613, 278 + xy: 557, 199 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1252,7 +1280,7 @@ chainbullet index: -1 circle rotate: false - xy: 342, 176 + xy: 791, 494 size: 17, 17 orig: 17, 17 offset: 0, 0 @@ -1266,35 +1294,35 @@ circle2 index: -1 blastenemy-t1 rotate: false - xy: 141, 114 + xy: 1008, 497 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 blastenemy-t2 rotate: false - xy: 123, 78 + xy: 141, 96 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 blastenemy-t3 rotate: false - xy: 141, 98 + xy: 159, 114 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 empenemy-t1 rotate: false - xy: 157, 114 + xy: 141, 80 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 empenemy-t2 rotate: false - xy: 157, 98 + xy: 342, 141 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1343,7 +1371,7 @@ flamerenemy-t2 index: -1 flamerenemy-t3 rotate: false - xy: 415, 179 + xy: 653, 366 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1371,133 +1399,133 @@ fortressenemy-t3 index: -1 healerenemy-t1 rotate: false - xy: 431, 182 + xy: 653, 350 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 healerenemy-t2 rotate: false - xy: 653, 366 + xy: 653, 334 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 healerenemy-t3 rotate: false - xy: 653, 350 + xy: 653, 318 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mortarenemy-t1 rotate: false - xy: 778, 459 + xy: 810, 479 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mortarenemy-t2 rotate: false - xy: 794, 479 + xy: 794, 462 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 mortarenemy-t3 rotate: false - xy: 794, 463 + xy: 810, 463 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 rapidenemy-t1 rotate: false - xy: 810, 479 + xy: 826, 479 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 rapidenemy-t2 rotate: false - xy: 810, 463 + xy: 826, 463 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 rapidenemy-t3 rotate: false - xy: 826, 479 + xy: 842, 479 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 standardenemy-t1 rotate: false - xy: 826, 463 + xy: 842, 463 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 targetenemy-t1 rotate: false - xy: 826, 463 + xy: 842, 463 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 standardenemy-t2 rotate: false - xy: 958, 481 + xy: 974, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 standardenemy-t3 rotate: false - xy: 972, 481 + xy: 988, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 tankenemy-t1 rotate: false - xy: 842, 479 + xy: 858, 479 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 tankenemy-t2 rotate: false - xy: 842, 463 + xy: 858, 463 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 tankenemy-t3 rotate: false - xy: 858, 479 + xy: 874, 479 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 titanenemy-t1 rotate: false - xy: 87, 76 + xy: 123, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titanenemy-t2 rotate: false - xy: 105, 94 + xy: 105, 76 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 titanenemy-t3 rotate: false - xy: 123, 112 + xy: 123, 94 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -1511,63 +1539,63 @@ enemyarrow index: -1 icon-coal rotate: false - xy: 888, 455 + xy: 450, 204 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 888, 445 + xy: 460, 215 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 888, 435 + xy: 460, 205 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-sand rotate: false - xy: 892, 465 + xy: 450, 194 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 898, 455 + xy: 460, 195 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 898, 445 + xy: 448, 184 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 898, 435 + xy: 452, 174 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 902, 465 + xy: 458, 184 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laser rotate: false - xy: 687, 382 + xy: 175, 116 size: 1, 12 orig: 1, 12 offset: 0, 0 @@ -1581,56 +1609,56 @@ laserend index: -1 laserfull rotate: false - xy: 316, 149 + xy: 342, 175 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 mech-standard rotate: false - xy: 874, 481 + xy: 890, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mech-standard-icon rotate: false - xy: 888, 481 + xy: 904, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 ship-standard rotate: false - xy: 930, 481 + xy: 946, 481 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 998, 435 + xy: 579, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 1008, 445 + xy: 589, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 1008, 435 + xy: 589, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 358, 166 + xy: 139, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1729,7 +1757,7 @@ check-over index: -1 clear rotate: false - xy: 651, 382 + xy: 663, 382 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1757,28 +1785,28 @@ discord-banner-over index: -1 controller-cursor rotate: false - xy: 361, 177 + xy: 810, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-about rotate: false - xy: 653, 334 + xy: 706, 440 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-add rotate: false - xy: 653, 318 + xy: 736, 436 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-admin rotate: false - xy: 706, 440 + xy: 752, 436 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1792,77 +1820,77 @@ icon-admin-small index: -1 icon-areaDelete rotate: false - xy: 669, 370 + xy: 669, 358 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow rotate: false - xy: 736, 436 + xy: 178, 122 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-arrow-down rotate: false - xy: 669, 358 + xy: 669, 346 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-left rotate: false - xy: 669, 346 + xy: 669, 334 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-right rotate: false - xy: 669, 334 + xy: 669, 322 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-up rotate: false - xy: 669, 322 + xy: 736, 424 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-back rotate: false - xy: 827, 495 + xy: 398, 177 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-ban rotate: false - xy: 752, 436 + xy: 208, 119 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-cancel rotate: false - xy: 178, 122 + xy: 224, 119 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-chat rotate: false - xy: 575, 272 + xy: 748, 424 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-check rotate: false - xy: 173, 106 + xy: 240, 119 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1890,49 +1918,49 @@ icon-close-over index: -1 icon-crafting rotate: false - xy: 587, 272 + xy: 760, 424 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-cursor rotate: false - xy: 73, 36 + xy: 575, 272 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-defense rotate: false - xy: 557, 245 + xy: 587, 272 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-dev-builds rotate: false - xy: 208, 119 + xy: 49, 10 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-discord rotate: false - xy: 224, 119 + xy: 416, 179 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-distribution rotate: false - xy: 557, 233 + xy: 73, 36 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-donate rotate: false - xy: 240, 119 + xy: 432, 182 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1960,35 +1988,35 @@ icon-exit index: -1 icon-file-text rotate: false - xy: 49, 10 + xy: 312, 127 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-fill rotate: false - xy: 397, 177 + xy: 846, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-floppy rotate: false - xy: 525, 237 + xy: 342, 125 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-folder rotate: false - xy: 541, 237 + xy: 525, 237 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-folder-parent rotate: false - xy: 173, 90 + xy: 541, 237 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2009,21 +2037,21 @@ icon-google-play index: -1 icon-grid rotate: false - xy: 845, 495 + xy: 864, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-hold rotate: false - xy: 557, 221 + xy: 178, 110 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-holdDelete rotate: false - xy: 557, 209 + xy: 557, 245 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2037,112 +2065,112 @@ icon-home index: -1 icon-host rotate: false - xy: 525, 221 + xy: 304, 111 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-info rotate: false - xy: 688, 420 + xy: 557, 233 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-itch.io rotate: false - xy: 541, 221 + xy: 525, 221 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-line rotate: false - xy: 863, 495 + xy: 882, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-link rotate: false - xy: 509, 213 + xy: 541, 221 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-load rotate: false - xy: 304, 111 + xy: 509, 213 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-load-image rotate: false - xy: 881, 495 + xy: 900, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-load-map rotate: false - xy: 899, 495 + xy: 918, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-loading rotate: false - xy: 917, 495 + xy: 936, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-menu rotate: false - xy: 683, 408 + xy: 557, 221 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-none rotate: false - xy: 683, 396 + xy: 557, 209 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pause rotate: false - xy: 704, 428 + xy: 352, 113 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pencil rotate: false - xy: 935, 495 + xy: 954, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-pencil-small rotate: false - xy: 312, 127 + xy: 320, 111 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-pick rotate: false - xy: 953, 495 + xy: 972, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-play rotate: false - xy: 681, 370 + xy: 1002, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2156,21 +2184,21 @@ icon-play-2 index: -1 icon-players rotate: false - xy: 681, 358 + xy: 681, 370 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-power rotate: false - xy: 681, 346 + xy: 681, 358 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-production rotate: false - xy: 681, 334 + xy: 681, 346 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2184,14 +2212,14 @@ icon-quit index: -1 icon-redo rotate: false - xy: 971, 495 + xy: 990, 495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-refresh rotate: false - xy: 320, 111 + xy: 336, 109 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2205,7 +2233,7 @@ icon-rename index: -1 icon-resize rotate: false - xy: 989, 495 + xy: 656, 426 size: 16, 16 orig: 16, 16 offset: 0, 0 @@ -2240,119 +2268,119 @@ icon-rotate-right index: -1 icon-save rotate: false - xy: 342, 160 + xy: 667, 410 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-save-image rotate: false - xy: 1007, 495 + xy: 69, 110 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-save-map rotate: false - xy: 656, 426 + xy: 69, 92 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-settings rotate: false - xy: 681, 322 + xy: 681, 334 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-terrain rotate: false - xy: 69, 110 + xy: 69, 74 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-tools rotate: false - xy: 667, 410 + xy: 667, 394 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-touch rotate: false - xy: 675, 310 + xy: 681, 322 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-touchDelete rotate: false - xy: 675, 298 + xy: 675, 310 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-trash rotate: false - xy: 667, 394 + xy: 762, 474 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-trash-16 rotate: false - xy: 69, 92 + xy: 87, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-trello rotate: false - xy: 688, 432 + xy: 762, 458 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-tutorial rotate: false - xy: 762, 474 + xy: 778, 475 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-undo rotate: false - xy: 69, 74 + xy: 87, 94 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-weapon rotate: false - xy: 716, 428 + xy: 675, 298 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-wiki rotate: false - xy: 762, 458 + xy: 778, 459 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-zoom rotate: false - xy: 87, 112 + xy: 105, 112 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-zoom-small rotate: false - xy: 778, 475 + xy: 794, 478 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2423,14 +2451,14 @@ scroll-knob-vertical-black index: -1 selection rotate: false - xy: 791, 492 + xy: 424, 195 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 slider rotate: false - xy: 1022, 465 + xy: 599, 274 size: 1, 8 orig: 1, 8 offset: 0, 0 @@ -2502,7 +2530,7 @@ textfield-over index: -1 white rotate: false - xy: 173, 125 + xy: 69, 1 size: 3, 3 orig: 3, 3 offset: 0, 0 @@ -2532,77 +2560,77 @@ beam index: -1 beam-equip rotate: false - xy: 1014, 485 + xy: 565, 274 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blaster rotate: false - xy: 139, 78 + xy: 782, 426 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blaster-equip rotate: false - xy: 149, 78 + xy: 73, 26 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 clustergun rotate: false - xy: 623, 275 + xy: 352, 103 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 clustergun-equip rotate: false - xy: 633, 275 + xy: 1014, 477 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shockgun rotate: false - xy: 1012, 465 + xy: 589, 242 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shockgun-equip rotate: false - xy: 1008, 455 + xy: 589, 232 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 triblaster rotate: false - xy: 368, 167 + xy: 149, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 triblaster-equip rotate: false - xy: 378, 167 + xy: 159, 8 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 vulcan rotate: false - xy: 447, 188 + xy: 200, 109 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 vulcan-equip rotate: false - xy: 201, 79 + xy: 210, 109 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 3e75f75a9c40577a38d61e766369fa4401ec91a3..077a888d4428a536365dcf865b6fa88530703766 100644 GIT binary patch literal 94754 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 literal 92976 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