reformat code

- fix color identity
- service pool is working good on android now so use it on generating map
This commit is contained in:
Anthony Calosa
2022-08-09 09:17:19 +08:00
parent 36e7687034
commit c8073a333c
2 changed files with 224 additions and 258 deletions

View File

@@ -33,9 +33,9 @@ public class World implements Disposable, SaveFileContent {
private Pixmap biomeImage; private Pixmap biomeImage;
private long[][] biomeMap; private long[][] biomeMap;
private int[][] terrainMap; private int[][] terrainMap;
private static final int collisionBit =0b10000000000000000000000000000000; private static final int collisionBit = 0b10000000000000000000000000000000;
private static final int isStructureBit=0b01000000000000000000000000000000; private static final int isStructureBit = 0b01000000000000000000000000000000;
private static final int terrainMask =collisionBit|isStructureBit; private static final int terrainMask = collisionBit | isStructureBit;
private int width; private int width;
private int height; private int height;
private SpritesDataMap mapObjectIds; private SpritesDataMap mapObjectIds;
@@ -43,38 +43,38 @@ public class World implements Disposable, SaveFileContent {
private BiomeTexture[] biomeTexture; private BiomeTexture[] biomeTexture;
private long seed; private long seed;
private final Random random = new Random(); private final Random random = new Random();
private boolean worldDataLoaded=false; private boolean worldDataLoaded = false;
private Texture globalTexture = null; private Texture globalTexture = null;
public Random getRandom() public Random getRandom() {
{
return random; return random;
} }
static public int highestBiome(long biome) { static public int highestBiome(long biome) {
return (int) (Math.log(Long.highestOneBit(biome)) / Math.log(2)); return (int) (Math.log(Long.highestOneBit(biome)) / Math.log(2));
} }
public boolean collidingTile(Rectangle boundingRect) public boolean collidingTile(Rectangle boundingRect) {
{
int xLeft=(int) boundingRect.getX() / getTileSize(); int xLeft = (int) boundingRect.getX() / getTileSize();
int yTop=(int) boundingRect.getY() / getTileSize(); int yTop = (int) boundingRect.getY() / getTileSize();
int xRight=(int) ((boundingRect.getX()+boundingRect.getWidth()) / getTileSize()); int xRight = (int) ((boundingRect.getX() + boundingRect.getWidth()) / getTileSize());
int yBottom= (int) ((boundingRect.getY()+boundingRect.getHeight()) / getTileSize()); int yBottom = (int) ((boundingRect.getY() + boundingRect.getHeight()) / getTileSize());
if(isColliding(xLeft,yTop)) if (isColliding(xLeft, yTop))
return true; return true;
if(isColliding(xLeft,yBottom)) if (isColliding(xLeft, yBottom))
return true; return true;
if(isColliding(xRight,yBottom)) if (isColliding(xRight, yBottom))
return true; return true;
if(isColliding(xRight,yTop)) if (isColliding(xRight, yTop))
return true; return true;
return false; return false;
} }
public void loadWorldData() { public void loadWorldData() {
if(worldDataLoaded) if (worldDataLoaded)
return; return;
FileHandle handle = Config.instance().getFile(Paths.WORLD); FileHandle handle = Config.instance().getFile(Paths.WORLD);
@@ -82,52 +82,51 @@ public class World implements Disposable, SaveFileContent {
this.data = (new Json()).fromJson(WorldData.class, rawJson); this.data = (new Json()).fromJson(WorldData.class, rawJson);
biomeTexture = new BiomeTexture[data.GetBiomes().size() + 1]; biomeTexture = new BiomeTexture[data.GetBiomes().size() + 1];
int biomeIndex=0; int biomeIndex = 0;
for (BiomeData biome : data.GetBiomes()) { for (BiomeData biome : data.GetBiomes()) {
biomeTexture[biomeIndex] = new BiomeTexture(biome, data.tileSize); biomeTexture[biomeIndex] = new BiomeTexture(biome, data.tileSize);
biomeIndex++; biomeIndex++;
} }
biomeTexture[biomeIndex] = new BiomeTexture(data.roadTileset, data.tileSize); biomeTexture[biomeIndex] = new BiomeTexture(data.roadTileset, data.tileSize);
worldDataLoaded=true; worldDataLoaded = true;
} }
@Override @Override
public void load(SaveFileData saveFileData) { public void load(SaveFileData saveFileData) {
if(biomeImage!=null) if (biomeImage != null)
biomeImage.dispose(); biomeImage.dispose();
loadWorldData(); loadWorldData();
biomeImage=saveFileData.readPixmap("biomeImage"); biomeImage = saveFileData.readPixmap("biomeImage");
biomeMap=(long[][])saveFileData.readObject("biomeMap"); biomeMap = (long[][]) saveFileData.readObject("biomeMap");
terrainMap=(int[][])saveFileData.readObject("terrainMap"); terrainMap = (int[][]) saveFileData.readObject("terrainMap");
width = saveFileData.readInt("width");
width=saveFileData.readInt("width"); height = saveFileData.readInt("height");
height=saveFileData.readInt("height");
mapObjectIds = new SpritesDataMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize()); mapObjectIds = new SpritesDataMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize());
mapObjectIds.load(saveFileData.readSubData("mapObjectIds")); mapObjectIds.load(saveFileData.readSubData("mapObjectIds"));
mapPoiIds = new PointOfInterestMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize(),this.data.height / getChunkSize()); mapPoiIds = new PointOfInterestMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize(), this.data.height / getChunkSize());
mapPoiIds.load(saveFileData.readSubData("mapPoiIds")); mapPoiIds.load(saveFileData.readSubData("mapPoiIds"));
seed=saveFileData.readLong("seed"); seed = saveFileData.readLong("seed");
} }
@Override @Override
public SaveFileData save() { public SaveFileData save() {
SaveFileData data=new SaveFileData(); SaveFileData data = new SaveFileData();
data.store("biomeImage",biomeImage); data.store("biomeImage", biomeImage);
data.storeObject("biomeMap",biomeMap); data.storeObject("biomeMap", biomeMap);
data.storeObject("terrainMap",terrainMap); data.storeObject("terrainMap", terrainMap);
data.store("width",width); data.store("width", width);
data.store("height",height); data.store("height", height);
data.store("mapObjectIds",mapObjectIds.save()); data.store("mapObjectIds", mapObjectIds.save());
data.store("mapPoiIds",mapPoiIds.save()); data.store("mapPoiIds", mapPoiIds.save());
data.store("seed",seed); data.store("seed", seed);
return data; return data;
@@ -137,6 +136,7 @@ public class World implements Disposable, SaveFileContent {
public BiomeSpriteData getObject(int id) { public BiomeSpriteData getObject(int id) {
return mapObjectIds.get(id); return mapObjectIds.get(id);
} }
private class DrawingInformation { private class DrawingInformation {
private int neighbors; private int neighbors;
@@ -151,9 +151,10 @@ public class World implements Disposable, SaveFileContent {
} }
public void draw(Pixmap drawingPixmap) { public void draw(Pixmap drawingPixmap) {
regions.drawPixmapOn(terrain,neighbors,drawingPixmap); regions.drawPixmapOn(terrain, neighbors, drawingPixmap);
} }
} }
public Pixmap getBiomeSprite(int x, int y) { public Pixmap getBiomeSprite(int x, int y) {
if (x < 0 || y <= 0 || x >= width || y > height) if (x < 0 || y <= 0 || x >= width || y > height)
return new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888); return new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888);
@@ -161,7 +162,7 @@ public class World implements Disposable, SaveFileContent {
long biomeIndex = getBiome(x, y); long biomeIndex = getBiome(x, y);
int biomeTerrain = getTerrainIndex(x, y); int biomeTerrain = getTerrainIndex(x, y);
Pixmap drawingPixmap = new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888); Pixmap drawingPixmap = new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888);
ArrayList<DrawingInformation> information=new ArrayList<>(); ArrayList<DrawingInformation> information = new ArrayList<>();
for (int i = 0; i < biomeTexture.length; i++) { for (int i = 0; i < biomeTexture.length; i++) {
if ((biomeIndex & 1L << i) == 0) { if ((biomeIndex & 1L << i) == 0) {
continue; continue;
@@ -182,44 +183,40 @@ public class World implements Disposable, SaveFileContent {
int otherTerrain = getTerrainIndex(x + nx, y + ny); int otherTerrain = getTerrainIndex(x + nx, y + ny);
if ((otherBiome & 1L << i) != 0 && (biomeTerrain == otherTerrain)|biomeTerrain==0) if ((otherBiome & 1L << i) != 0 && (biomeTerrain == otherTerrain) | biomeTerrain == 0)
neighbors |= (1 << bitIndex); neighbors |= (1 << bitIndex);
bitIndex--; bitIndex--;
} }
} }
if(biomeTerrain!=0&&neighbors!=0b111_111_111) if (biomeTerrain != 0 && neighbors != 0b111_111_111) {
{
bitIndex = 8; bitIndex = 8;
int baseNeighbors=0; int baseNeighbors = 0;
for (int ny = 1; ny > -2; ny--) { for (int ny = 1; ny > -2; ny--) {
for (int nx = -1; nx < 2; nx++) { for (int nx = -1; nx < 2; nx++) {
if ((getBiome(x + nx, y + ny) & (1L << i)) != 0 ) if ((getBiome(x + nx, y + ny) & (1L << i)) != 0)
baseNeighbors |= (1 << bitIndex); baseNeighbors |= (1 << bitIndex);
bitIndex--; bitIndex--;
} }
} }
information.add(new DrawingInformation(baseNeighbors,regions,0) ); information.add(new DrawingInformation(baseNeighbors, regions, 0));
} }
information.add(new DrawingInformation(neighbors,regions,biomeTerrain) ); information.add(new DrawingInformation(neighbors, regions, biomeTerrain));
} }
int lastFullNeighbour=-1; int lastFullNeighbour = -1;
int counter=0; int counter = 0;
for(DrawingInformation info:information) for (DrawingInformation info : information) {
{ if (info.neighbors == 0b111_111_111)
if(info.neighbors==0b111_111_111) lastFullNeighbour = counter;
lastFullNeighbour= counter;
counter++; counter++;
} }
counter=0; counter = 0;
if(lastFullNeighbour<0&&information.size()!=0) if (lastFullNeighbour < 0 && information.size() != 0)
information.get(0).neighbors=0b111_111_111; information.get(0).neighbors = 0b111_111_111;
for(DrawingInformation info:information) for (DrawingInformation info : information) {
{ if (counter < lastFullNeighbour) {
if(counter<lastFullNeighbour)
{
counter++; counter++;
continue; continue;
} }
@@ -231,14 +228,15 @@ public class World implements Disposable, SaveFileContent {
public int getTerrainIndex(int x, int y) { public int getTerrainIndex(int x, int y) {
try { try {
return terrainMap[x][height - y-1] & ~terrainMask; return terrainMap[x][height - y - 1] & ~terrainMask;
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
return 0; return 0;
} }
} }
public boolean isStructure(int x, int y) { public boolean isStructure(int x, int y) {
try { try {
return (terrainMap[x][height - y-1] & ~isStructureBit)!=0; return (terrainMap[x][height - y - 1] & ~isStructureBit) != 0;
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
return false; return false;
} }
@@ -246,44 +244,43 @@ public class World implements Disposable, SaveFileContent {
public long getBiome(int x, int y) { public long getBiome(int x, int y) {
try { try {
return biomeMap[x][height - y-1]; return biomeMap[x][height - y - 1];
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
return biomeMap[biomeMap.length-1][biomeMap[biomeMap.length-1].length-1]; return biomeMap[biomeMap.length - 1][biomeMap[biomeMap.length - 1].length - 1];
} }
} }
public boolean isColliding(int x, int y) { public boolean isColliding(int x, int y) {
try { try {
return (terrainMap[x][height - y-1] & collisionBit)!=0; return (terrainMap[x][height - y - 1] & collisionBit) != 0;
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
return true; return true;
} }
} }
public WorldData getData() { public WorldData getData() {
return data; return data;
} }
private void clearTerrain(int x,int y,int size)
{
for(int xclear=-size;xclear<size;xclear++) private void clearTerrain(int x, int y, int size) {
for(int yclear=-size;yclear<size;yclear++)
{ for (int xclear = -size; xclear < size; xclear++)
for (int yclear = -size; yclear < size; yclear++) {
try { try {
terrainMap[x+xclear][height-1-(y+yclear)]=0; terrainMap[x + xclear][height - 1 - (y + yclear)] = 0;
} } catch (ArrayIndexOutOfBoundsException e) {
catch (ArrayIndexOutOfBoundsException e)
{
} }
} }
} }
private long measureGenerationTime(String msg,long lastTime)
{ private long measureGenerationTime(String msg, long lastTime) {
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
System.out.print("\n"+msg+" :\t\t"+((currentTime-lastTime)/1000f)+" s"); System.out.print("\n" + msg + " :\t\t" + ((currentTime - lastTime) / 1000f) + " s");
return currentTime; return currentTime;
} }
public World generateNew(long seed) { public World generateNew(long seed) {
if (GuiBase.isAndroid()) if (GuiBase.isAndroid())
GuiBase.getInterface().preventSystemSleep(true); GuiBase.getInterface().preventSystemSleep(true);
@@ -327,16 +324,7 @@ private long measureGenerationTime(String msg,long lastTime)
int biomeWidth = (int) Math.round(biome.width * (double) width); int biomeWidth = (int) Math.round(biome.width * (double) width);
int biomeHeight = (int) Math.round(biome.height * (double) height); int biomeHeight = (int) Math.round(biome.height * (double) height);
for (BiomeStructureData data : biome.structures) { for (BiomeStructureData data : biome.structures) {
long localSeed=seed; long localSeed = seed;
if (GuiBase.isAndroid()) {
FThreads.invokeInEdtNowOrLater(() -> {
long threadStartTime = System.currentTimeMillis();
BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight);
structure.initialize();
structureDataMap.put(data, structure);
measureGenerationTime("wavefunctioncollapse " + data.sourcePath, threadStartTime);
});
} else {
ThreadUtil.getServicePool().submit(() -> { ThreadUtil.getServicePool().submit(() -> {
long threadStartTime = System.currentTimeMillis(); long threadStartTime = System.currentTimeMillis();
BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight); BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight);
@@ -347,7 +335,6 @@ private long measureGenerationTime(String msg,long lastTime)
} }
} }
} }
}
FThreads.invokeInEdtNowOrLater(() -> { FThreads.invokeInEdtNowOrLater(() -> {
for (BiomeData biome : data.GetBiomes()) { for (BiomeData biome : data.GetBiomes()) {
@@ -359,8 +346,8 @@ private long measureGenerationTime(String msg,long lastTime)
int beginX = Math.max(biomeXStart - biomeWidth / 2, 0); int beginX = Math.max(biomeXStart - biomeWidth / 2, 0);
int beginY = Math.max(biomeYStart - biomeHeight / 2, 0); int beginY = Math.max(biomeYStart - biomeHeight / 2, 0);
int endX = Math.min(biomeXStart + biomeWidth/2, width); int endX = Math.min(biomeXStart + biomeWidth / 2, width);
int endY = Math.min(biomeYStart + biomeHeight/2, height); int endY = Math.min(biomeYStart + biomeHeight / 2, height);
if (biome.width == 1.0 && biome.height == 1.0) { if (biome.width == 1.0 && biome.height == 1.0) {
beginX = 0; beginX = 0;
beginY = 0; beginY = 0;
@@ -370,10 +357,10 @@ private long measureGenerationTime(String msg,long lastTime)
for (int x = beginX; x < endX; x++) { for (int x = beginX; x < endX; x++) {
for (int y = beginY; y < endY; y++) { for (int y = beginY; y < endY; y++) {
//value 0-1 based on noise //value 0-1 based on noise
float noiseValue = ((float)noise.eval(x / (float) width * noiseZoom, y / (float) height * noiseZoom) + 1) / 2f; float noiseValue = ((float) noise.eval(x / (float) width * noiseZoom, y / (float) height * noiseZoom) + 1) / 2f;
noiseValue *= biome.noiseWeight; noiseValue *= biome.noiseWeight;
//value 0-1 based on dist to origin //value 0-1 based on dist to origin
float distanceValue = ((float)Math.sqrt((x - biomeXStart) * (x - biomeXStart) + (y - biomeYStart) * (y - biomeYStart))) / (Math.max(biomeWidth, biomeHeight) / 2f); float distanceValue = ((float) Math.sqrt((x - biomeXStart) * (x - biomeXStart) + (y - biomeYStart) * (y - biomeYStart))) / (Math.max(biomeWidth, biomeHeight) / 2f);
distanceValue *= biome.distWeight; distanceValue *= biome.distWeight;
if (noiseValue + distanceValue < 1.0 || biome.invertHeight && (1 - noiseValue) + distanceValue < 1.0) { if (noiseValue + distanceValue < 1.0 || biome.invertHeight && (1 - noiseValue) + distanceValue < 1.0) {
Color color = biome.GetColor(); Color color = biome.GetColor();
@@ -385,27 +372,22 @@ private long measureGenerationTime(String msg,long lastTime)
pix.setColor(color.r, color.g, color.b, 1); pix.setColor(color.r, color.g, color.b, 1);
pix.drawPixel(x, y); pix.drawPixel(x, y);
biomeMap[x][y] |= (1L << biomeIndex[0]); biomeMap[x][y] |= (1L << biomeIndex[0]);
int terrainCounter=1; int terrainCounter = 1;
terrainMap[x][y]=0; terrainMap[x][y] = 0;
if(biome.terrain!=null) if (biome.terrain != null) {
{ for (BiomeTerrainData terrain : biome.terrain) {
for(BiomeTerrainData terrain:biome.terrain) float terrainNoise = ((float) noise.eval(x / (float) width * (noiseZoom * terrain.resolution), y / (float) height * (noiseZoom * terrain.resolution)) + 1) / 2;
{ if (terrainNoise >= terrain.min && terrainNoise <= terrain.max) {
float terrainNoise = ((float)noise.eval(x / (float) width * (noiseZoom*terrain.resolution), y / (float) height * (noiseZoom*terrain.resolution)) + 1) / 2; terrainMap[x][y] = terrainCounter;
if(terrainNoise>=terrain.min&&terrainNoise<=terrain.max)
{
terrainMap[x][y]=terrainCounter;
} }
terrainCounter++; terrainCounter++;
} }
} }
if(biome.collision) if (biome.collision)
terrainMap[x][y]|=collisionBit; terrainMap[x][y] |= collisionBit;
if(biome.structures!=null) if (biome.structures != null) {
{ for (BiomeStructureData data : biome.structures) {
for(BiomeStructureData data:biome.structures) while (!structureDataMap.containsKey(data)) {
{
while(!structureDataMap.containsKey(data)) {
try { try {
Thread.sleep(10); Thread.sleep(10);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -413,23 +395,22 @@ private long measureGenerationTime(String msg,long lastTime)
} }
} }
BiomeStructure structure=structureDataMap.get(data); BiomeStructure structure = structureDataMap.get(data);
int structureXStart= x-(biomeXStart - biomeWidth / 2)-(int) ((data.x*biomeWidth)-(data.width*biomeWidth/2)); int structureXStart = x - (biomeXStart - biomeWidth / 2) - (int) ((data.x * biomeWidth) - (data.width * biomeWidth / 2));
int structureYStart= y-(biomeYStart - biomeHeight / 2)- (int) ((data.y*biomeHeight)-(data.height*biomeHeight/2)); int structureYStart = y - (biomeYStart - biomeHeight / 2) - (int) ((data.y * biomeHeight) - (data.height * biomeHeight / 2));
int structureIndex=structure.objectID(structureXStart,structureYStart); int structureIndex = structure.objectID(structureXStart, structureYStart);
if(structureIndex>=0) if (structureIndex >= 0) {
{
pix.setColor(data.mappingInfo[structureIndex].getColor()); pix.setColor(data.mappingInfo[structureIndex].getColor());
pix.drawPixel(x, y); pix.drawPixel(x, y);
terrainMap[x][y]=terrainCounter+structureIndex; terrainMap[x][y] = terrainCounter + structureIndex;
if(structure.collision(structureXStart,structureYStart)) if (structure.collision(structureXStart, structureYStart))
terrainMap[x][y]|=collisionBit; terrainMap[x][y] |= collisionBit;
terrainMap[x][y]|=isStructureBit; terrainMap[x][y] |= isStructureBit;
} }
terrainCounter+=structure.structureObjectCount(); terrainCounter += structure.structureObjectCount();
} }
} }
} }
@@ -437,23 +418,23 @@ private long measureGenerationTime(String msg,long lastTime)
} }
} }
} }
currentTime[0] =measureGenerationTime("biomes in total", currentTime[0]); currentTime[0] = measureGenerationTime("biomes in total", currentTime[0]);
mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(),data.height / getChunkSize()); mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(), data.height / getChunkSize());
List<PointOfInterest> towns = new ArrayList<>(); List<PointOfInterest> towns = new ArrayList<>();
List<PointOfInterest> notTowns = new ArrayList<>(); List<PointOfInterest> notTowns = new ArrayList<>();
List<Rectangle> otherPoints = new ArrayList<>(); List<Rectangle> otherPoints = new ArrayList<>();
clearTerrain((int) (data.width*data.playerStartPosX), (int) (data.height*data.playerStartPosY),10); clearTerrain((int) (data.width * data.playerStartPosX), (int) (data.height * data.playerStartPosY), 10);
otherPoints.add(new Rectangle(((float)data.width*data.playerStartPosX*(float)data.tileSize)-data.tileSize*3,((float)data.height*data.playerStartPosY*data.tileSize)-data.tileSize*3,data.tileSize*6,data.tileSize*6)); otherPoints.add(new Rectangle(((float) data.width * data.playerStartPosX * (float) data.tileSize) - data.tileSize * 3, ((float) data.height * data.playerStartPosY * data.tileSize) - data.tileSize * 3, data.tileSize * 6, data.tileSize * 6));
int biomeIndex2=-1; int biomeIndex2 = -1;
for (BiomeData biome : data.GetBiomes()) { for (BiomeData biome : data.GetBiomes()) {
biomeIndex2++; biomeIndex2++;
for (PointOfInterestData poi : biome.getPointsOfInterest()) { for (PointOfInterestData poi : biome.getPointsOfInterest()) {
for (int i = 0; i < poi.count; i++) { for (int i = 0; i < poi.count; i++) {
for (int counter = 0; counter < 500; counter++)//tries 100 times to find a free point for (int counter = 0; counter < 500; counter++)//tries 100 times to find a free point
{ {
float radius = (float) Math.sqrt(((random.nextDouble())/2 * poi.radiusFactor)); float radius = (float) Math.sqrt(((random.nextDouble()) / 2 * poi.radiusFactor));
float theta = (float) (random.nextDouble() * 2 * Math.PI); float theta = (float) (random.nextDouble() * 2 * Math.PI);
float x = (float) (radius * Math.cos(theta)); float x = (float) (radius * Math.cos(theta));
x *= (biome.width * width / 2); x *= (biome.width * width / 2);
@@ -462,13 +443,12 @@ private long measureGenerationTime(String msg,long lastTime)
y *= (biome.height * height / 2); y *= (biome.height * height / 2);
y += (height - (biome.startPointY * height)); y += (height - (biome.startPointY * height));
if((int)x<0||(int)y<=0||(int)y>=height||(int)x>=width|| biomeIndex2!= highestBiome(getBiome((int)x,(int)y))) if ((int) x < 0 || (int) y <= 0 || (int) y >= height || (int) x >= width || biomeIndex2 != highestBiome(getBiome((int) x, (int) y))) {
{
continue; continue;
} }
x*= data.tileSize; x *= data.tileSize;
y*= data.tileSize; y *= data.tileSize;
boolean breakNextLoop = false; boolean breakNextLoop = false;
for (Rectangle rect : otherPoints) { for (Rectangle rect : otherPoints) {
@@ -477,44 +457,37 @@ private long measureGenerationTime(String msg,long lastTime)
break; break;
} }
} }
if (breakNextLoop) if (breakNextLoop) {
{ boolean foundSolution = false;
boolean foundSolution=false; boolean noSolution = false;
boolean noSolution=false; breakNextLoop = false;
breakNextLoop=false; for (int xi = -1; xi < 2 && !foundSolution; xi++) {
for(int xi=-1;xi<2&&!foundSolution;xi++) for (int yi = -1; yi < 2 && !foundSolution; yi++) {
{
for(int yi=-1;yi<2&&!foundSolution;yi++)
{
for (Rectangle rect : otherPoints) { for (Rectangle rect : otherPoints) {
if (rect.contains(x+xi*data.tileSize, y+yi*data.tileSize)) { if (rect.contains(x + xi * data.tileSize, y + yi * data.tileSize)) {
noSolution = true; noSolution = true;
break; break;
} }
} }
if(!noSolution) if (!noSolution) {
{ foundSolution = true;
foundSolution=true; x = x + xi * data.tileSize;
x=x+xi*data.tileSize; y = y + yi * data.tileSize;
y=y+yi*data.tileSize;
} }
} }
} }
if(!foundSolution) if (!foundSolution) {
{ if (counter == 499) {
if(counter==499) System.err.print("Can not place POI " + poi.name + "\n");
{
System.err.print("Can not place POI "+poi.name+"\n");
} }
continue; continue;
} }
} }
otherPoints.add(new Rectangle(x - data.tileSize * 4, y - data.tileSize * 4, data.tileSize * 8, data.tileSize * 8)); otherPoints.add(new Rectangle(x - data.tileSize * 4, y - data.tileSize * 4, data.tileSize * 8, data.tileSize * 8));
PointOfInterest newPoint = new PointOfInterest(poi, new Vector2(x, y), random); PointOfInterest newPoint = new PointOfInterest(poi, new Vector2(x, y), random);
clearTerrain((int)(x/data.tileSize),(int)(y/data.tileSize),3); clearTerrain((int) (x / data.tileSize), (int) (y / data.tileSize), 3);
mapPoiIds.add(newPoint); mapPoiIds.add(newPoint);
@@ -523,11 +496,9 @@ private long measureGenerationTime(String msg,long lastTime)
pix.fillRectangle((int) x / data.tileSize - 3, height - (int) y / data.tileSize - 3, 6, 6); pix.fillRectangle((int) x / data.tileSize - 3, height - (int) y / data.tileSize - 3, 6, 6);
if (poi.type!=null&&poi.type.equals("town")) { if (poi.type != null && poi.type.equals("town")) {
towns.add(newPoint); towns.add(newPoint);
} } else {
else
{
notTowns.add(newPoint); notTowns.add(newPoint);
} }
break; break;
@@ -537,12 +508,12 @@ private long measureGenerationTime(String msg,long lastTime)
} }
} }
currentTime[0] =measureGenerationTime("poi placement", currentTime[0]); currentTime[0] = measureGenerationTime("poi placement", currentTime[0]);
//sort towns //sort towns
List<Pair<PointOfInterest, PointOfInterest>> allSortedTowns = new ArrayList<>(); List<Pair<PointOfInterest, PointOfInterest>> allSortedTowns = new ArrayList<>();
HashSet<Long> usedEdges=new HashSet<>();//edge is first 32 bits id of first id and last 32 bits id of second HashSet<Long> usedEdges = new HashSet<>();//edge is first 32 bits id of first id and last 32 bits id of second
for (int i = 0; i < towns.size() - 1; i++) { for (int i = 0; i < towns.size() - 1; i++) {
PointOfInterest current = towns.get(i); PointOfInterest current = towns.get(i);
@@ -551,28 +522,28 @@ private long measureGenerationTime(String msg,long lastTime)
float smallestDistance = Float.MAX_VALUE; float smallestDistance = Float.MAX_VALUE;
for (int j = 0; j < towns.size(); j++) { for (int j = 0; j < towns.size(); j++) {
if(i==j||usedEdges.contains((long)i|((long)j<<32))) if (i == j || usedEdges.contains((long) i | ((long) j << 32)))
continue; continue;
float dist = current.getPosition().dst(towns.get(j).getPosition()); float dist = current.getPosition().dst(towns.get(j).getPosition());
if(dist>data.maxRoadDistance) if (dist > data.maxRoadDistance)
continue; continue;
if (dist < smallestDistance) { if (dist < smallestDistance) {
smallestDistance = dist; smallestDistance = dist;
secondSmallestIndex=smallestIndex; secondSmallestIndex = smallestIndex;
smallestIndex = j; smallestIndex = j;
} }
} }
if (smallestIndex < 0) if (smallestIndex < 0)
continue; continue;
usedEdges.add((long)i|((long)smallestIndex<<32)); usedEdges.add((long) i | ((long) smallestIndex << 32));
usedEdges.add((long)i<<32|((long)smallestIndex)); usedEdges.add((long) i << 32 | ((long) smallestIndex));
allSortedTowns.add(Pair.of(current, towns.get(smallestIndex))); allSortedTowns.add(Pair.of(current, towns.get(smallestIndex)));
if (secondSmallestIndex < 0) if (secondSmallestIndex < 0)
continue; continue;
usedEdges.add((long)i|((long)secondSmallestIndex<<32)); usedEdges.add((long) i | ((long) secondSmallestIndex << 32));
usedEdges.add((long)i<<32|((long)secondSmallestIndex)); usedEdges.add((long) i << 32 | ((long) secondSmallestIndex));
//allSortedTowns.add(Pair.of(current, towns.get(secondSmallestIndex))); //allSortedTowns.add(Pair.of(current, towns.get(secondSmallestIndex)));
} }
List<Pair<PointOfInterest, PointOfInterest>> allPOIPathsToNextTown = new ArrayList<>(); List<Pair<PointOfInterest, PointOfInterest>> allPOIPathsToNextTown = new ArrayList<>();
@@ -600,33 +571,29 @@ private long measureGenerationTime(String msg,long lastTime)
//reset terrain path to the next town //reset terrain path to the next town
for (Pair<PointOfInterest, PointOfInterest> poiToTown : allPOIPathsToNextTown) { for (Pair<PointOfInterest, PointOfInterest> poiToTown : allPOIPathsToNextTown) {
int startX= (int) poiToTown.getKey().getTilePosition(data.tileSize).x; int startX = (int) poiToTown.getKey().getTilePosition(data.tileSize).x;
int startY= (int) poiToTown.getKey().getTilePosition(data.tileSize).y; int startY = (int) poiToTown.getKey().getTilePosition(data.tileSize).y;
int x1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).x; int x1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).x;
int y1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).y; int y1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).y;
int dx = Math.abs( x1 - startX); int dx = Math.abs(x1 - startX);
int dy = Math.abs( y1 - startY); int dy = Math.abs(y1 - startY);
int sx = startX < x1 ? 1 : -1; int sx = startX < x1 ? 1 : -1;
int sy = startY < y1 ? 1 : -1; int sy = startY < y1 ? 1 : -1;
int err = dx - dy; int err = dx - dy;
int e2; int e2;
while (true) while (true) {
{ if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
if( startX<0|| startY<=0|| startX>=width|| startY>height)continue; if ((terrainMap[startX][height - startY] & collisionBit) != 0)//clear terrain if it has collision
if((terrainMap[startX][height - startY]&collisionBit)!=0)//clear terrain if it has collision terrainMap[startX][height - startY] = 0;
terrainMap[startX][height - startY]=0;
pix.drawPixel(startX, height - startY); pix.drawPixel(startX, height - startY);
if (startX == x1 && startY == y1) if (startX == x1 && startY == y1)
break; break;
e2 = 2 * err; e2 = 2 * err;
if (e2 > -dy) if (e2 > -dy) {
{
err = err - dy; err = err - dy;
startX = startX + sx; startX = startX + sx;
} } else if (e2 < dx) {
else if (e2 < dx)
{
err = err + dx; err = err + dx;
startY = startY + sy; startY = startY + sy;
} }
@@ -635,63 +602,59 @@ private long measureGenerationTime(String msg,long lastTime)
for (Pair<PointOfInterest, PointOfInterest> townPair : allSortedTowns) { for (Pair<PointOfInterest, PointOfInterest> townPair : allSortedTowns) {
int startX= (int) townPair.getKey().getTilePosition(data.tileSize).x; int startX = (int) townPair.getKey().getTilePosition(data.tileSize).x;
int startY= (int) townPair.getKey().getTilePosition(data.tileSize).y; int startY = (int) townPair.getKey().getTilePosition(data.tileSize).y;
int x1 = (int) townPair.getValue().getTilePosition(data.tileSize).x; int x1 = (int) townPair.getValue().getTilePosition(data.tileSize).x;
int y1 = (int) townPair.getValue().getTilePosition(data.tileSize).y; int y1 = (int) townPair.getValue().getTilePosition(data.tileSize).y;
for (int x = startX - 1; x < startX + 2; x++) { for (int x = startX - 1; x < startX + 2; x++) {
for (int y = startY - 1; y < startY + 2; y++) { for (int y = startY - 1; y < startY + 2; y++) {
if(x<0||y<=0||x>=width||y>height)continue; if (x < 0 || y <= 0 || x >= width || y > height) continue;
biomeMap[x][height - y-1] |= (1L << biomeIndex[0]); biomeMap[x][height - y - 1] |= (1L << biomeIndex[0]);
terrainMap[x][height-y-1]=0; terrainMap[x][height - y - 1] = 0;
pix.drawPixel(x, height-y); pix.drawPixel(x, height - y);
} }
} }
int dx = Math.abs( x1 - startX); int dx = Math.abs(x1 - startX);
int dy = Math.abs( y1 - startY); int dy = Math.abs(y1 - startY);
int sx = startX < x1 ? 1 : -1; int sx = startX < x1 ? 1 : -1;
int sy = startY < y1 ? 1 : -1; int sy = startY < y1 ? 1 : -1;
int err = dx - dy; int err = dx - dy;
int e2; int e2;
while (true) while (true) {
{ if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
if( startX<0|| startY<=0|| startX>=width|| startY>height)continue;
biomeMap[startX][height - startY] |= (1L << biomeIndex[0]); biomeMap[startX][height - startY] |= (1L << biomeIndex[0]);
terrainMap[startX][height - startY]=0; terrainMap[startX][height - startY] = 0;
pix.drawPixel(startX, height - startY); pix.drawPixel(startX, height - startY);
if (startX == x1 && startY == y1) if (startX == x1 && startY == y1)
break; break;
e2 = 2 * err; e2 = 2 * err;
if (e2 > -dy) if (e2 > -dy) {
{
err = err - dy; err = err - dy;
startX = startX + sx; startX = startX + sx;
} } else if (e2 < dx) {
else if (e2 < dx)
{
err = err + dx; err = err + dx;
startY = startY + sy; startY = startY + sy;
} }
} }
} }
currentTime[0] =measureGenerationTime("roads", currentTime[0]); currentTime[0] = measureGenerationTime("roads", currentTime[0]);
mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize()); mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize());
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
int invertedHeight = height - y -1; int invertedHeight = height - y - 1;
int currentBiome = highestBiome(biomeMap[x][invertedHeight]); int currentBiome = highestBiome(biomeMap[x][invertedHeight]);
if (currentBiome >= data.GetBiomes().size()) if (currentBiome >= data.GetBiomes().size())
continue;//roads continue;//roads
if(isStructure(x,y)) if (isStructure(x, y))
continue; continue;
BiomeData biome = data.GetBiomes().get(currentBiome); BiomeData biome = data.GetBiomes().get(currentBiome);
for (String name : biome.spriteNames) { for (String name : biome.spriteNames) {
BiomeSpriteData sprite = data.GetBiomeSprites().getSpriteData(name); BiomeSpriteData sprite = data.GetBiomeSprites().getSpriteData(name);
double spriteNoise = (noise.eval(x / (double) width * noiseZoom*sprite.resolution, y / (double) invertedHeight * noiseZoom*sprite.resolution) + 1) / 2; double spriteNoise = (noise.eval(x / (double) width * noiseZoom * sprite.resolution, y / (double) invertedHeight * noiseZoom * sprite.resolution) + 1) / 2;
if (spriteNoise >= sprite.startArea && spriteNoise <= sprite.endArea) { if (spriteNoise >= sprite.startArea && spriteNoise <= sprite.endArea) {
if (random.nextFloat() <= sprite.density) { if (random.nextFloat() <= sprite.density) {
String spriteKey = sprite.key(); String spriteKey = sprite.key();
@@ -702,7 +665,7 @@ private long measureGenerationTime(String msg,long lastTime)
} else { } else {
key = mapObjectIds.intKey(spriteKey); key = mapObjectIds.intKey(spriteKey);
} }
mapObjectIds.putPosition(key, new Vector2((((float) x)+.25f+random.nextFloat()/2) * data.tileSize , (((float) y+.25f)-random.nextFloat()/2) * data.tileSize )); mapObjectIds.putPosition(key, new Vector2((((float) x) + .25f + random.nextFloat() / 2) * data.tileSize, (((float) y + .25f) - random.nextFloat() / 2) * data.tileSize));
break;//only on sprite per point break;//only on sprite per point
} }
} }
@@ -712,7 +675,7 @@ private long measureGenerationTime(String msg,long lastTime)
biomeImage = pix; biomeImage = pix;
measureGenerationTime("sprites", currentTime[0]); measureGenerationTime("sprites", currentTime[0]);
}); });
System.out.print("\nGenerating world took :\t\t"+((System.currentTimeMillis()-startTime)/1000f)+" s\n"); System.out.print("\nGenerating world took :\t\t" + ((System.currentTimeMillis() - startTime) / 1000f) + " s\n");
WorldStage.getInstance().clearCache(); WorldStage.getInstance().clearCache();
ThreadUtil.getServicePool().shutdownNow(); ThreadUtil.getServicePool().shutdownNow();
ThreadUtil.refreshServicePool(); ThreadUtil.refreshServicePool();
@@ -768,8 +731,9 @@ private long measureGenerationTime(String msg,long lastTime)
public PointOfInterest findPointsOfInterest(String name) { public PointOfInterest findPointsOfInterest(String name) {
return mapPoiIds.findPointsOfInterest(name); return mapPoiIds.findPointsOfInterest(name);
} }
public int getChunkSize() { public int getChunkSize() {
return (Scene.getIntendedWidth()>Scene.getIntendedHeight()?Scene.getIntendedWidth():Scene.getIntendedHeight()) / data.tileSize; return (Scene.getIntendedWidth() > Scene.getIntendedHeight() ? Scene.getIntendedWidth() : Scene.getIntendedHeight()) / data.tileSize;
} }
public void dispose() { public void dispose() {
@@ -778,11 +742,11 @@ private long measureGenerationTime(String msg,long lastTime)
} }
public void setSeed(long seedOffset) { public void setSeed(long seedOffset) {
random.setSeed(seedOffset+seed); random.setSeed(seedOffset + seed);
} }
public Texture getGlobalTexture() { public Texture getGlobalTexture() {
if(globalTexture == null){ if (globalTexture == null) {
globalTexture = new Texture(Config.instance().getFile("ui/sprite_markers.png")); globalTexture = new Texture(Config.instance().getFile("ui/sprite_markers.png"));
System.out.print("Loading auxiliary sprites.\n"); System.out.print("Loading auxiliary sprites.\n");
} }

View File

@@ -23,51 +23,48 @@ import java.util.zip.InflaterInputStream;
*/ */
public class WorldSave { public class WorldSave {
static final public int AUTO_SAVE_SLOT =-1; static final public int AUTO_SAVE_SLOT = -1;
static final public int QUICK_SAVE_SLOT =-2; static final public int QUICK_SAVE_SLOT = -2;
static final public int INVALID_SAVE_SLOT =-3; static final public int INVALID_SAVE_SLOT = -3;
static final WorldSave currentSave=new WorldSave(); static final WorldSave currentSave = new WorldSave();
public WorldSaveHeader header = new WorldSaveHeader(); public WorldSaveHeader header = new WorldSaveHeader();
private final AdventurePlayer player=new AdventurePlayer(); private final AdventurePlayer player = new AdventurePlayer();
private final World world=new World(); private final World world = new World();
private final PointOfInterestChanges.Map pointOfInterestChanges= new PointOfInterestChanges.Map(); private final PointOfInterestChanges.Map pointOfInterestChanges = new PointOfInterestChanges.Map();
private final SignalList onLoadList=new SignalList(); private final SignalList onLoadList = new SignalList();
public final World getWorld() public final World getWorld() {
{
return world; return world;
} }
public AdventurePlayer getPlayer()
{ public AdventurePlayer getPlayer() {
return player; return player;
} }
public void onLoad(Runnable run) public void onLoad(Runnable run) {
{
onLoadList.add(run); onLoadList.add(run);
} }
public PointOfInterestChanges getPointOfInterestChanges(String id)
{ public PointOfInterestChanges getPointOfInterestChanges(String id) {
if(!pointOfInterestChanges.containsKey(id)) if (!pointOfInterestChanges.containsKey(id))
pointOfInterestChanges.put(id,new PointOfInterestChanges()); pointOfInterestChanges.put(id, new PointOfInterestChanges());
return pointOfInterestChanges.get(id); return pointOfInterestChanges.get(id);
} }
static public boolean load(int currentSlot) { static public boolean load(int currentSlot) {
String fileName = WorldSave.getSaveFile(currentSlot); String fileName = WorldSave.getSaveFile(currentSlot);
if(!new File(fileName).exists()) if (!new File(fileName).exists())
return false; return false;
new File(getSaveDir()).mkdirs(); new File(getSaveDir()).mkdirs();
try { try {
try(FileInputStream fos = new FileInputStream(fileName); try (FileInputStream fos = new FileInputStream(fileName);
InflaterInputStream inf = new InflaterInputStream(fos); InflaterInputStream inf = new InflaterInputStream(fos);
ObjectInputStream oos = new ObjectInputStream(inf)) ObjectInputStream oos = new ObjectInputStream(inf)) {
{
currentSave.header = (WorldSaveHeader) oos.readObject(); currentSave.header = (WorldSaveHeader) oos.readObject();
SaveFileData mainData=(SaveFileData)oos.readObject(); SaveFileData mainData = (SaveFileData) oos.readObject();
currentSave.player.load(mainData.readSubData("player")); currentSave.player.load(mainData.readSubData("player"));
GamePlayerUtil.getGuiPlayer().setName(currentSave.player.getName()); GamePlayerUtil.getGuiPlayer().setName(currentSave.player.getName());
try { try {
@@ -89,9 +86,11 @@ public class WorldSave {
} }
return true; return true;
} }
public static boolean isSafeFile(String name) { public static boolean isSafeFile(String name) {
return filenameToSlot(name)!= INVALID_SAVE_SLOT; return filenameToSlot(name) != INVALID_SAVE_SLOT;
} }
static public int filenameToSlot(String name) { static public int filenameToSlot(String name) {
if (name.equals("auto_save.sav")) if (name.equals("auto_save.sav"))
return AUTO_SAVE_SLOT; return AUTO_SAVE_SLOT;
@@ -133,6 +132,7 @@ public class WorldSave {
identity = dp.getColorIdentityforAdventure(); identity = dp.getColorIdentityforAdventure();
} else { } else {
starterDeck = isFantasy ? DeckgenUtil.getRandomOrPreconOrThemeDeck("", false, false, false) : Config.instance().starterDecks()[startingColorIdentity]; starterDeck = isFantasy ? DeckgenUtil.getRandomOrPreconOrThemeDeck("", false, false, false) : Config.instance().starterDecks()[startingColorIdentity];
identity = DeckProxy.getColorIdentityforAdventure(starterDeck);
} }
currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex, isFantasy, diff); currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex, isFantasy, diff);
currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize())); currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize()));
@@ -146,14 +146,17 @@ public class WorldSave {
} }
public boolean autoSave() { public boolean autoSave() {
return save("auto save",AUTO_SAVE_SLOT); return save("auto save", AUTO_SAVE_SLOT);
} }
public boolean quickSave() { public boolean quickSave() {
return save("quick save",QUICK_SAVE_SLOT); return save("quick save", QUICK_SAVE_SLOT);
} }
public boolean quickLoad() { public boolean quickLoad() {
return load(QUICK_SAVE_SLOT); return load(QUICK_SAVE_SLOT);
} }
public boolean save(String text, int currentSlot) { public boolean save(String text, int currentSlot) {
header.name = text; header.name = text;
@@ -161,17 +164,16 @@ public class WorldSave {
new File(getSaveDir()).mkdirs(); new File(getSaveDir()).mkdirs();
try { try {
try(FileOutputStream fos = new FileOutputStream(fileName); try (FileOutputStream fos = new FileOutputStream(fileName);
DeflaterOutputStream def= new DeflaterOutputStream(fos); DeflaterOutputStream def = new DeflaterOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(def)) ObjectOutputStream oos = new ObjectOutputStream(def)) {
{ header.saveDate = new Date();
header.saveDate= new Date();
oos.writeObject(header); oos.writeObject(header);
SaveFileData mainData=new SaveFileData(); SaveFileData mainData = new SaveFileData();
mainData.store("player",currentSave.player.save()); mainData.store("player", currentSave.player.save());
mainData.store("world",currentSave.world.save()); mainData.store("world", currentSave.world.save());
mainData.store("worldStage", WorldStage.getInstance().save()); mainData.store("worldStage", WorldStage.getInstance().save());
mainData.store("pointOfInterestChanges",currentSave.pointOfInterestChanges.save()); mainData.store("pointOfInterestChanges", currentSave.pointOfInterestChanges.save());
oos.writeObject(mainData); oos.writeObject(mainData);
} }