diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 3e33254ea7..30c211761c 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -111,6 +111,10 @@ public class World extends Module{ return currentSector; } + public void setSector(Sector currentSector){ + this.currentSector = currentSector; + } + public void setMap(Map map){ this.currentMap = map; } @@ -222,7 +226,7 @@ public class World extends Module{ beginMapLoad(); - int width = sectorSize, height = sectorSize; + int width = sectorSize * sector.size, height = sectorSize * sector.size; Tile[][] tiles = createTiles(width, height); diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index ffa10fdf7b..ab6705f3ea 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -31,9 +31,7 @@ public class BlockRenderer{ } } - /** - * Process all blocks to draw, simultaneously drawing block shadows and static blocks. - */ + /**Process all blocks to draw, simultaneously drawing block shadows.*/ public void processBlocks(){ requestidx = 0; lastLayer = null; diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index 647ec56d9f..40b0f5c42c 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -17,6 +17,7 @@ import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.CacheBatch; import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Mathf; @@ -28,6 +29,7 @@ import static io.anuke.mindustry.Vars.world; public class FloorRenderer{ private final static int chunksize = 64; + private int gutter; private Chunk[][] cache; private CacheBatch cbatch; private IntSet drawnLayerSet = new IntSet(); @@ -76,15 +78,18 @@ public class FloorRenderer{ int crangex = (int) (camera.viewportWidth * camera.zoom / (chunksize * tilesize)) + 1; int crangey = (int) (camera.viewportHeight * camera.zoom / (chunksize * tilesize)) + 1; + int camx = Mathf.scl(camera.position.x, chunksize * tilesize); + int camy = Mathf.scl(camera.position.y, chunksize * tilesize); + 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; + int worldx = camx + x; + int worldy = camy + y; if(!Mathf.inBounds(worldx, worldy, cache)) continue; - fillChunk(worldx * chunksize * tilesize, worldy * chunksize * tilesize); + fillChunk((worldx) * chunksize * tilesize, (worldy) * chunksize * tilesize); } } @@ -96,8 +101,8 @@ public class FloorRenderer{ //preliminary layer check 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; + int worldx = camx + x; + int worldy = camy + y; if(!Mathf.inBounds(worldx, worldy, cache)) continue; @@ -184,7 +189,7 @@ public class FloorRenderer{ private void fillChunk(float x, float y){ Draw.color(Color.GRAY); - Draw.crect("white", x, y, chunksize * tilesize, chunksize * tilesize); + Fill.crect(x, y, chunksize * tilesize, chunksize * tilesize); Draw.color(); } @@ -195,7 +200,7 @@ public class FloorRenderer{ 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 tile = world.tile(tilex - gutter, tiley - gutter); if(tile != null){ used.add(tile.floor().cacheLayer); } @@ -214,8 +219,11 @@ public class FloorRenderer{ 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; + Tile tile = world.tile(tilex - gutter, tiley - gutter); + if(tile == null){ + Fill.rect((tilex - gutter) * tilesize, (tiley - gutter) * tilesize, tilesize, tilesize); + continue; + } if(tile.floor().cacheLayer == layer){ tile.floor().draw(tile); @@ -235,7 +243,14 @@ public class FloorRenderer{ Timers.mark(); - int chunksx = Mathf.ceil((float) world.width() / chunksize), chunksy = Mathf.ceil((float) world.height() / chunksize); + if(world.getSector() != null){ + gutter = 32; + }else{ + gutter = 0; + } + + int chunksx = Mathf.ceil((float) (world.width() + gutter) / chunksize), + chunksy = Mathf.ceil((float) (world.height() + gutter) / chunksize) ; cache = new Chunk[chunksx][chunksy]; cbatch = new CacheBatch(world.width() * world.height() * 4 * 4); diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 901213df7d..df86ee2191 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -9,9 +9,9 @@ import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.game.Version; +import io.anuke.mindustry.io.SaveFileVersion; +import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.BlockPart; @@ -38,7 +38,7 @@ public class Save16 extends SaveFileVersion{ stream.readLong(); //time stream.readLong(); //total playtime stream.readInt(); //build - stream.readInt(); //sector ID + int sector = stream.readInt(); //sector ID //general state byte mode = stream.readByte(); @@ -46,6 +46,8 @@ public class Save16 extends SaveFileVersion{ Map map = world.maps().getByName(mapname); world.setMap(map); + world.setSector(world.sectors().get(sector)); + int wave = stream.readInt(); byte difficulty = stream.readByte(); float wavetime = stream.readFloat(); diff --git a/core/src/io/anuke/mindustry/maps/Sectors.java b/core/src/io/anuke/mindustry/maps/Sectors.java index a6cb3ed5a5..bfa1087861 100644 --- a/core/src/io/anuke/mindustry/maps/Sectors.java +++ b/core/src/io/anuke/mindustry/maps/Sectors.java @@ -8,15 +8,17 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult; import io.anuke.mindustry.world.ColorMapper; +import io.anuke.mindustry.world.Edges; import io.anuke.ucore.core.Settings; -import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.GridMap; +import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class Sectors{ private static final int sectorImageSize = 16; - private static final float sectorLargeChance = 0.1f; + private static final float sectorLargeChance = 0.15f; private GridMap grid = new GridMap<>(); @@ -29,26 +31,43 @@ public class Sectors{ return grid.get(x, y); } + public Sector get(int position){ + return grid.get(Bits.getLeftShort(position), Bits.getRightShort(position)); + } + /**Unlocks a sector. This shows nearby sectors.*/ public void completeSector(int x, int y){ createSector(x, y); Sector sector = get(x, y); sector.complete = true; - for(GridPoint2 point : Geometry.d4){ + for(GridPoint2 point : Edges.getEdges(sector.size)){ createSector(sector.x + point.x, sector.y + point.y); } } /**Creates a sector at a location if it is not present, but does not unlock it.*/ public void createSector(int x, int y){ + boolean isLarge = Mathf.randomSeed(Bits.packInt((short)round2(x), (short)round2(y))) < sectorLargeChance; + + if(isLarge){ + x = round2(x); + y = round2(y); + } + if(grid.containsKey(x, y)) return; Sector sector = new Sector(); sector.x = (short)x; sector.y = (short)y; sector.complete = false; - grid.put(x, y, sector); + sector.size = isLarge ? 2 : 1; + + for(int cx = 0; cx < sector.size; cx++){ + for(int cy = 0; cy < sector.size; cy++){ + grid.put(x + cx, y + cy, sector); + } + } if(sector.texture == null) createTexture(sector); } @@ -58,7 +77,11 @@ public class Sectors{ for(Sector sector : out){ createTexture(sector); - grid.put(sector.x, sector.y, sector); + for(int cx = 0; cx < sector.size; cx++){ + for(int cy = 0; cy < sector.size; cy++){ + grid.put(sector.x + cx, sector.y + cy, sector); + } + } } if(out.size == 0){ @@ -77,20 +100,27 @@ public class Sectors{ Settings.save(); } + private int round2(int i){ + if(i < 0){ + i --; + } + return i/2*2; + } + private void createTexture(Sector sector){ if(headless) return; //obviously not created or needed on server - Pixmap pixmap = new Pixmap(sectorImageSize, sectorImageSize, Format.RGBA8888); + Pixmap pixmap = new Pixmap(sectorImageSize * sector.size, sectorImageSize * sector.size, Format.RGBA8888); - for(int x = 0; x < sectorImageSize; x++){ - for(int y = 0; y < sectorImageSize; y++){ + for(int x = 0; x < pixmap.getWidth(); x++){ + for(int y = 0; y < pixmap.getHeight(); y++){ int toX = x * sectorSize / sectorImageSize; int toY = y * sectorSize / sectorImageSize; GenResult result = world.generator().generateTile(sector.x, sector.y, toX, toY); int color = ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation); - pixmap.drawPixel(x, sectorImageSize - 1 - y, color); + pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index ea72f70cac..17ca964915 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -59,6 +59,10 @@ public class SectorsDialog extends FloatingDialog{ } }); }).size(230f, 64f).name("deploy-button").disabled(b -> selected == null); + + if(debug){ + buttons().addButton("unlock", () -> world.sectors().completeSector(selected.x, selected.y)).size(230f, 64f).disabled(b -> selected == null); + } } void selectSector(Sector sector){ @@ -67,11 +71,11 @@ public class SectorsDialog extends FloatingDialog{ } class SectorView extends Element{ - float panX, panY; float lastX, lastY; float sectorSize = 100f; float sectorPadding = 14f; boolean clicked = false; + float panX = -sectorPadding/2f, panY = -sectorSize/2f; SectorView(){ addListener(new InputListener(){ @@ -132,10 +136,19 @@ public class SectorsDialog extends FloatingDialog{ float drawY = y + height/2f + sectorY * padSectorSize - offsetY * padSectorSize - panY % padSectorSize; Sector sector = world.sectors().get(sectorX, sectorY); + int size = (sector == null ? 1 : sector.size); + float padding = (size-1) * sectorPadding; + + if(sector != null && (sector.x != sectorX || sector.y != sectorY)){ + continue; + } + + drawX += (size-1)/2f*padSectorSize; + drawY += (size-1)/2f*padSectorSize; if(sector != null && sector.texture != null){ Draw.color(Color.WHITE); - Draw.rect(sector.texture, drawX, drawY, sectorSize, sectorSize); + Draw.rect(sector.texture, drawX, drawY, sectorSize * size + padding, sectorSize * size + padding); } float stroke = 4f; @@ -145,7 +158,8 @@ public class SectorsDialog extends FloatingDialog{ }else if(sector == selected){ Draw.color(Palette.place); stroke = 6f; - }else if(Mathf.inRect(mouse.x, mouse.y, drawX - padSectorSize/2f, drawY - padSectorSize/2f, drawX + padSectorSize/2f, drawY + padSectorSize/2f)){ + }else if(Mathf.inRect(mouse.x, mouse.y, drawX - padSectorSize/2f * size, drawY - padSectorSize/2f * size, + drawX + padSectorSize/2f * size, drawY + padSectorSize/2f * size)){ if(clicked){ selectSector(sector); } @@ -157,7 +171,7 @@ public class SectorsDialog extends FloatingDialog{ } Lines.stroke(stroke); - Lines.crect(drawX, drawY, sectorSize, sectorSize, (int)stroke); + Lines.crect(drawX, drawY, sectorSize * size + padding, sectorSize * size + padding, (int)stroke); } }