From 475efc38d2a647200cde725ff6d9988aa7cd0aa0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 7 Dec 2017 14:23:43 -0500 Subject: [PATCH] Optmizied drawing of map --- build.gradle | 2 +- .../src/io/anuke/mindustry/core/Renderer.java | 163 ++++++++++-------- core/src/io/anuke/mindustry/core/UI.java | 6 +- .../anuke/mindustry/editor/EditorControl.java | 9 +- .../anuke/mindustry/entities/effect/EMP.java | 4 +- .../entities/enemies/BlastEnemy.java | 9 +- .../mindustry/entities/enemies/EmpEnemy.java | 2 +- .../mindustry/ui/MindustrySettingsDialog.java | 12 ++ core/src/io/anuke/mindustry/world/Block.java | 4 - .../anuke/mindustry/world/blocks/Blocks.java | 15 +- .../mindustry/world/blocks/types/Floor.java | 7 +- .../world/blocks/types/StaticBlock.java | 11 ++ desktop/mindustry-saves/7.mins | Bin 3824 -> 2866 bytes .../mindustry/desktop/DesktopLauncher.java | 2 +- 14 files changed, 151 insertions(+), 95 deletions(-) create mode 100644 core/src/io/anuke/mindustry/world/blocks/types/StaticBlock.java diff --git a/build.gradle b/build.gradle index 5371ac6f3b..3bce61141a 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,7 @@ project(":core") { apply plugin: "java" dependencies { - compile 'com.github.Anuken:ucore:a64bf7e' + compile 'com.github.Anuken:ucore:bd4474d8e5' compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx-ai:1.8.1" } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index e1b5203697..cccd55a5a3 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -5,9 +5,7 @@ import static io.anuke.ucore.core.Core.camera; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Buttons; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.*; import com.badlogic.gdx.graphics.profiling.GLProfiler; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; @@ -25,27 +23,33 @@ import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.ProductionBlocks; +import io.anuke.mindustry.world.blocks.types.StaticBlock; import io.anuke.ucore.UCore; import io.anuke.ucore.core.*; import io.anuke.ucore.entities.DestructibleEntity; +import io.anuke.ucore.entities.EffectEntity; import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.graphics.Cache; -import io.anuke.ucore.graphics.Caches; +import io.anuke.ucore.graphics.CacheBatch; import io.anuke.ucore.modules.RendererModule; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.util.*; public class Renderer extends RendererModule{ - String[] surfaces = {"shadow", "shield", "pixel", "indicators"}; + String[] surfaces = { "shadow", "shield", "pixel", "indicators" }; int targetscale = baseCameraScale; int chunksize = 32; - Cache[][] floorCache; + int[][][] cache; FloatArray shieldHits = new FloatArray(); float shieldHitDuration = 18f; + CacheBatch cbatch; public Renderer() { Core.cameraScale = baseCameraScale; + Effects.setEffectProvider((name, color, x, y, rotation) -> { + if(Settings.getBool("effects")) + new EffectEntity(name, color, rotation).set(x, y).add(); + }); } @Override @@ -101,8 +105,7 @@ public class Renderer extends RendererModule{ updateShake(0.75f); float prevx = camera.position.x, prevy = camera.position.y; - clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f, - world.height() * tilesize - tilesize / 2f); + clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f, world.height() * tilesize - tilesize / 2f); float deltax = camera.position.x - prex, deltay = camera.position.y - prey; @@ -131,9 +134,7 @@ public class Renderer extends RendererModule{ Profiler.end("draw"); if(Profiler.updating()) - Profiler.getTimes().put("draw", Profiler.getTimes().get("draw") - - Profiler.getTimes().get("blockDraw") - - Profiler.getTimes().get("entityDraw")); + Profiler.getTimes().put("draw", Profiler.getTimes().get("draw") - Profiler.getTimes().get("blockDraw") - Profiler.getTimes().get("entityDraw")); if(Vars.debug && Vars.debugGL && Timers.get("profile", 60)){ UCore.log("shaders: " + GLProfiler.shaderSwitches, "calls: " + GLProfiler.drawCalls, "bindings: " + GLProfiler.textureBindings, "vertices: " + GLProfiler.vertexCount.average); @@ -157,14 +158,14 @@ public class Renderer extends RendererModule{ Profiler.end("blockDraw"); Profiler.begin("entityDraw"); - + Graphics.shader(Shaders.outline, false); Entities.draw(control.enemyGroup); Graphics.shader(); - + Entities.draw(Entities.defaultGroup()); Entities.draw(control.bulletGroup); - + Profiler.end("entityDraw"); drawShield(); @@ -206,20 +207,20 @@ public class Renderer extends RendererModule{ } void drawShield(){ - for(int i = 0; i < shieldHits.size/3; i ++){ + for(int i = 0; i < shieldHits.size / 3; i++){ //float x = hits.get(i*3+0); //float y = hits.get(i*3+1); - float time = shieldHits.get(i*3+2); - + float time = shieldHits.get(i * 3 + 2); + time += Timers.delta() / shieldHitDuration; - shieldHits.set(i*3 + 2, time); - + shieldHits.set(i * 3 + 2, time); + if(time >= 1f){ - shieldHits.removeRange(i*3, i*3 + 2); - i --; + shieldHits.removeRange(i * 3, i * 3 + 2); + i--; } } - + Texture texture = Graphics.getSurface("shield").texture(); Shaders.shield.color.set(Color.SKY); @@ -237,7 +238,7 @@ public class Renderer extends RendererModule{ Graphics.end(); Graphics.beginCam(); } - + public void addShieldHit(float x, float y){ shieldHits.addAll(x, y, 0f); } @@ -246,12 +247,13 @@ public class Renderer extends RendererModule{ int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize; //render the entire map - if(floorCache == null || floorCache.length != chunksx || floorCache[0].length != chunksy){ - floorCache = new Cache[chunksx][chunksy]; + 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++){ - renderCache(x, y); + cacheChunk(x, y, true); + cacheChunk(x, y, false); } } } @@ -263,21 +265,7 @@ public class Renderer extends RendererModule{ int crangex = (int) (camera.viewportWidth / (chunksize * tilesize)) + 1; int crangey = (int) (camera.viewportHeight / (chunksize * tilesize)) + 1; - 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, floorCache)) - continue; - - if(floorCache[worldx][worldy] == null){ - renderCache(worldx, worldy); - } - - floorCache[worldx][worldy].render(); - } - } + drawCache(0, crangex, crangey); Graphics.begin(); @@ -287,31 +275,40 @@ public class Renderer extends RendererModule{ boolean noshadows = Settings.getBool("noshadows"); - boolean drawTiles = true; + boolean drawTiles = Settings.getBool("drawblocks"); //0 = shadows - //1 = normal blocks - //2 = over blocks - for(int l = (noshadows ? 1 : 0); l < (drawTiles ? 3 : 0); l++){ + //1 = cache blocks + //2 = normal blocks + //3 = over blocks + for(int l = (noshadows ? 1 : 0); l < (drawTiles ? 4 : 0); l++){ if(l == 0){ Graphics.surface("shadow"); } - for(int x = -rangex; x <= rangex; x++){ - for(int y = -rangey; y <= rangey; y++){ - int worldx = Mathf.scl(camera.position.x, tilesize) + x; - int worldy = Mathf.scl(camera.position.y, tilesize) + y; + if(l == 1){ + Graphics.end(); + drawCache(1, crangex, crangey); + Graphics.begin(); + }else{ + for(int x = -rangex; x <= rangex; x++){ + for(int y = -rangey; y <= rangey; y++){ + int worldx = Mathf.scl(camera.position.x, tilesize) + x; + int worldy = Mathf.scl(camera.position.y, tilesize) + y; - if(world.tile(worldx, worldy) != null){ - Tile tile = world.tile(worldx, worldy); - if(l == 0){ - if(tile.block() != Blocks.air && world.isAccessible(worldx, worldy)){ - tile.block().drawShadow(tile); + if(world.tile(worldx, worldy) != null){ + Tile tile = world.tile(worldx, worldy); + if(l == 0){ + if(tile.block() != Blocks.air && world.isAccessible(worldx, worldy)){ + tile.block().drawShadow(tile); + } + }else if(!(tile.block() instanceof StaticBlock)){ + if(l == 2){ + tile.block().draw(tile); + }else if(l == 3){ + tile.block().drawOver(tile); + } } - }else if(l == 1){ - tile.block().draw(tile); - }else if(l == 2){ - tile.block().drawOver(tile); } } } @@ -332,7 +329,7 @@ public class Renderer extends RendererModule{ 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, floorCache)) + if(!Mathf.inBounds(worldx, worldy, cache)) continue; Draw.linerect(worldx * chunksize * tilesize, worldy * chunksize * tilesize, chunksize * tilesize, chunksize * tilesize); } @@ -341,22 +338,50 @@ public class Renderer extends RendererModule{ } } - void renderCache(int cx, int cy){ - Caches.begin(1600); + 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){ + 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); - tile.floor().drawCache(tile); - + if(floor){ + tile.floor().draw(tile); + }else if(tile.block() instanceof StaticBlock){ + tile.block().draw(tile); + } } } - floorCache[cx][cy] = Caches.end(); - + Graphics.popBatch(); + cbatch.end(); + cache[cx][cy][floor ? 0 : 1] = cbatch.getLastCache(); } public void clearTiles(){ - floorCache = null; + cache = null; + if(cbatch != null) + cbatch.dispose(); + cbatch = new CacheBatch(256 * 256 * 3); } void renderPixelOverlay(){ @@ -477,11 +502,11 @@ public class Renderer extends RendererModule{ for(Enemy entity : control.enemyGroup.all()){ drawHealth(entity); } - + if(!Vars.android) drawHealth(player); } - + void drawHealth(DestructibleEntity dest){ if(dest instanceof Player && Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){ drawHealth((int) dest.x, (int) dest.y - 7f, dest.health, dest.maxhealth); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index cfe5ab9774..cc9151c122 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -171,9 +171,7 @@ public class UI extends SceneModule{ menu = new MenuDialog(); - prefs.sliderPref("difficulty", "Difficulty", 1, 0, 2, i -> { - return i == 0 ? "Easy" : i == 1 ? "Normal" : "Hard"; - }); + prefs.sliderPref("difficulty", "Difficulty", 1, 0, 2, i -> i == 0 ? "Easy" : i == 1 ? "Normal" : "Hard"); prefs.screenshakePref(); prefs.volumePrefs(); @@ -182,6 +180,8 @@ public class UI extends SceneModule{ prefs.checkPref("noshadows", "Disable shadows", false); prefs.checkPref("smoothcam", "Smooth Camera", true); prefs.checkPref("indicators", "Enemy Indicators", true); + prefs.checkPref("effects", "Display Effects", true); + prefs.checkPref("drawblocks", "Draw Blocks", true); prefs.checkPref("pixelate", "Pixelate Screen", true, b->{ if(b){ Graphics.getSurface("pixel").setScale(Core.cameraScale); diff --git a/core/src/io/anuke/mindustry/editor/EditorControl.java b/core/src/io/anuke/mindustry/editor/EditorControl.java index 0cb4046755..345f037ed4 100644 --- a/core/src/io/anuke/mindustry/editor/EditorControl.java +++ b/core/src/io/anuke/mindustry/editor/EditorControl.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.editor; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.graphics.Texture; @@ -9,6 +10,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.OrderedMap; import com.badlogic.gdx.utils.TimeUtils; +import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Generator; @@ -77,7 +79,12 @@ public class EditorControl extends Module{ } if(Inputs.keyUp(Keys.E)){ - PixmapIO.writePNG(Gdx.files.absolute("/home/anuke/Pictures/maps/out-" + TimeUtils.millis() + ".png"), pixmap); + try{ + ClassReflection.getMethod(PixmapIO.class, "writePNG", FileHandle.class, Pixmap.class) + .invoke(Gdx.files.absolute("/home/anuke/Pictures/maps/out-" + TimeUtils.millis() + ".png"), pixmap); + }catch (Exception e){ + throw new RuntimeException(e); + } } } } diff --git a/core/src/io/anuke/mindustry/entities/effect/EMP.java b/core/src/io/anuke/mindustry/entities/effect/EMP.java index b4b124e67c..61eba1aabd 100644 --- a/core/src/io/anuke/mindustry/entities/effect/EMP.java +++ b/core/src/io/anuke/mindustry/entities/effect/EMP.java @@ -14,7 +14,7 @@ import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; public class EMP extends TimedEntity{ - static final int maxTargets = 10; + static final int maxTargets = 8; static Array array = new Array<>(); int radius = 4; @@ -53,7 +53,7 @@ public class EMP extends TimedEntity{ if(tile != null && tile.block() instanceof PowerAcceptor){ PowerAcceptor p = (PowerAcceptor)tile.block(); p.setPower(tile, 0f); - tile.entity.damage(damage*2); //extra damage + tile.entity.damage((int)(damage*1.6f)); //extra damage } //entity may be null here, after the block is dead! diff --git a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java index 3ef4bf68c2..50c8d98901 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java @@ -1,9 +1,12 @@ package io.anuke.mindustry.entities.enemies; +import com.badlogic.gdx.math.Vector2; + import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.ucore.util.Tmp; public class BlastEnemy extends Enemy{ @@ -21,12 +24,14 @@ public class BlastEnemy extends Enemy{ void move(){ super.move(); float range = 10f; + Vector2 offset = Tmp.v3.setZero(); if(target instanceof TileEntity){ TileEntity e = (TileEntity)target; - range = (e.tile.block().width * Vars.tilesize) /2f + 6f; + range = (e.tile.block().width * Vars.tilesize) /2f + 8f; + offset.set(e.tile.block().getPlaceOffset()); } - if(target != null && target.distanceTo(this) < range){ + if(target != null && target.distanceTo(this.x - offset.x, this.y - offset.y) < range){ explode(); } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java index fc5c3abf03..0b1ab729e9 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java @@ -7,7 +7,7 @@ public class EmpEnemy extends Enemy{ public EmpEnemy() { speed = 0.3f; - reload = 60; + reload = 70; maxhealth = 210; range = 80f; bullet = BulletType.emp; diff --git a/core/src/io/anuke/mindustry/ui/MindustrySettingsDialog.java b/core/src/io/anuke/mindustry/ui/MindustrySettingsDialog.java index a22b4426d5..f4a13053a1 100644 --- a/core/src/io/anuke/mindustry/ui/MindustrySettingsDialog.java +++ b/core/src/io/anuke/mindustry/ui/MindustrySettingsDialog.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.utils.Align; import io.anuke.ucore.scene.ui.Image; +import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.SettingsDialog; import io.anuke.ucore.scene.ui.layout.Unit; @@ -16,6 +17,17 @@ public class MindustrySettingsDialog extends SettingsDialog{ getTitleTable().row(); getTitleTable().add(new Image("white")) .growX().height(3f).pad(4f).units(Unit.dp).get().setColor(Colors.get("accent")); + + content().remove(); + buttons().remove(); + + ScrollPane pane = new ScrollPane(content()); + pane.setFadeScrollBars(false); + + row(); + add(pane).expand().fill(); + row(); + add(buttons()).fillX(); } @Override diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index f4b9dd24fb..d3b0c8ccbc 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -205,10 +205,6 @@ public class Block{ return false; } - public void drawCache(Tile tile){ - - } - public void draw(Tile tile){ //note: multiblocks do not support rotation if(!isMultiblock()){ diff --git a/core/src/io/anuke/mindustry/world/blocks/Blocks.java b/core/src/io/anuke/mindustry/world/blocks/Blocks.java index 85ed54ce48..d9aa00ede7 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/Blocks.java @@ -10,6 +10,7 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.types.BlockPart; import io.anuke.mindustry.world.blocks.types.Floor; +import io.anuke.mindustry.world.blocks.types.StaticBlock; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Mathf; @@ -110,32 +111,32 @@ public class Blocks{ grass = new Floor("grass"), - sandblock = new Block("sandblock"){{ + sandblock = new StaticBlock("sandblock"){{ solid = true; variants = 3; }}, - snowblock = new Block("snowblock"){{ + snowblock = new StaticBlock("snowblock"){{ solid = true; variants = 3; }}, - stoneblock = new Block("stoneblock"){{ + stoneblock = new StaticBlock("stoneblock"){{ solid = true; variants = 3; }}, - blackstoneblock = new Block("blackstoneblock"){{ + blackstoneblock = new StaticBlock("blackstoneblock"){{ solid = true; variants = 3; }}, - grassblock = new Block("grassblock"){{ + grassblock = new StaticBlock("grassblock"){{ solid = true; variants = 2; }}, - mossblock = new Block("mossblock"){{ + mossblock = new StaticBlock("mossblock"){{ solid = true; }}, @@ -172,7 +173,7 @@ public class Blocks{ drops = new ItemStack(Item.stone, 3); }}, - dirtblock = new Block("dirtblock"){{ + dirtblock = new StaticBlock("dirtblock"){{ solid = true; }}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/Floor.java b/core/src/io/anuke/mindustry/world/blocks/types/Floor.java index 83f524c0a0..e82b670f0b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/Floor.java @@ -7,7 +7,6 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Draw; -import io.anuke.ucore.graphics.Caches; import io.anuke.ucore.util.Mathf; public class Floor extends Block{ @@ -18,10 +17,10 @@ public class Floor extends Block{ } @Override - public void drawCache(Tile tile){ + public void draw(Tile tile){ MathUtils.random.setSeed(tile.id()); - Caches.draw(variants > 0 ? (name() + MathUtils.random(1, variants)) : name(), tile.worldx(), tile.worldy()); + Draw.rect(variants > 0 ? (name() + MathUtils.random(1, variants)) : name(), tile.worldx(), tile.worldy()); for(int dx = -1; dx <= 1; dx ++){ for(int dy = -1; dy <= 1; dy ++){ @@ -50,7 +49,7 @@ public class Floor extends Block{ temp.setTexture(region.getTexture()); temp.setRegion(region.getRegionX()+x, region.getRegionY()+y+h, w, -h); - Caches.draw(temp, tile.worldx()-4 + rx, tile.worldy()-4 + ry, w, h); + Draw.crect(temp, tile.worldx()-4 + rx, tile.worldy()-4 + ry, w, h); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/StaticBlock.java b/core/src/io/anuke/mindustry/world/blocks/types/StaticBlock.java new file mode 100644 index 0000000000..4d375f0464 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/types/StaticBlock.java @@ -0,0 +1,11 @@ +package io.anuke.mindustry.world.blocks.types; + +import io.anuke.mindustry.world.Block; + +public class StaticBlock extends Block{ + + public StaticBlock(String name) { + super(name); + } + +} diff --git a/desktop/mindustry-saves/7.mins b/desktop/mindustry-saves/7.mins index d4afecb81ddbc83d43490d96e5b16f5c055a5f73..c4c689f2255ccf23eb75dad5cea5a72acfc3aefe 100644 GIT binary patch literal 2866 zcmZwH&2Jk;7zXfhO5uWf;6i$U3zr^Bi}(_V7Nyh*sA);o&I%{NZocCr>yIEPX&Yz~ z+i@HN0ZJ(!6^KHiak7bHr!Jwu0SQ47AOYgaKfxJ^cV_%Nsa#vi`nS*f&g|~&I7+Fz zl?wD9Y}@;{(x1T5fA`-P9J_iXcxc}ZIUiPcDRqCgwp$LfE&349hdbmjy-Vv(eb57U zt6=0(Yw+;QZvi>oqg3RieE+A^<^A%lRI5@K9)#8&f-XG*m8jUGCc9Uul9h~IrTQO3 z)uXOhNniYNRL7~FCy<@DlD_*knOBNp@{g!#s^=dd%+FCs9|!xzlhS^*+!eWsaElVO^aG zGsgjaF+GR=bT!GGdZz2>3)!rFS3L_i8Q0w;b8TjJ(mndZ=F=vdA!%<$pW`CoRsb{xdBV@C7ys~hUaotTa z*JftfAHH?jJ6|$4v$KyH&YgzyiI?#hCr%m3@(-K0q#vz7`IKwkmwrwCR?;_0%~Eq` zFmsveJBw=+tYqvK<;M&B zsZSyQGbnu-DpM88{~Xoq7f_xmQ;936`d>n$UqNeBl^VZ_YLS{>L6%sB%2eD(R;4!9 zk>$!ziOO#xt5%?mDpaN7TgW!4Tn*V86~B&b1uB-$HX#iQ1r+zC&O7 zduWbY_yO6}k5J_&$om;OMP+XyTcj#f?H5$zze3ZLPi_B>>ghkAbJWbA$jX0N{SW>O BFh2kQ literal 3824 zcmZwJT~JhI7zgl|6>a*ssEfu*kbwPCh_TIu3k_R65G!bolKF{Bi#lq8l9VM0f=M9I z7wWQ#ibV0@R}RL6q7sRsq5^B<$e3EwMO>6uUD|Wb?*C6Nof*&k-v9HS=e+0aIR}+e z&nOkP(&m5dFEvgnWzzO2rG1l|Gpqm6Oc{IB6XVpx(jt?-3zJ>s7&WovkrLe*D?4|% z?6PIzSQV}E zdo^4;ReCR2eX2lKm9EtK2U{yaTSz8t)gyI<2{(SBL^D48rnqlQlG3rwTFsai)_X^ zsGI6rk1S&Y)IbeV9UD>Yp}KOBU7@a0e^P&M#=L3oLw@Q$)v^WECGt&?P2Pa1A3{?; zh9(w5b<{!X8g*bh=5=V$6%$0o7AIBPwO}Q^>muYNWcT*fLa4P*Ugq5;W@zfhs0o6iTzCf2L zl$*+-Hc$mrGu296pkDqGoztl7uaK2c311^~Q0dgn8dP(sX!*-3n>>G$sF=MfOtMtH zV3&WfA!BpMxM{CGQ}5AA#q2YBBZ|n`ixkEC(03PAMorj{YRvx8*Ag3=Nxv2Hi8Tjv zu11mqgGB$^d zqw8=3;;7Vv$l9pMhma*5HqMZ&kL}7dPJXb%s0~qZ^~jv{q4N_TPvkBp1rp{JKUh} z^#{{WMKvNzY&1F>4Lr)Vc7lAD53!p4E#{f!L6uFqoN9&!DL-XvMRopBDEb(*m|A!o znfoMEMct5xN;WxLRvVOl8e0AXm0DVWr zbs=+7iPUE51hw@i91+(IRZ