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