mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
add missing translation, minor speedup generating map
This commit is contained in:
@@ -244,18 +244,21 @@ public class SaveLoadScene extends UIScene {
|
||||
loaded = false;
|
||||
if (WorldSave.load(currentSlot)) {
|
||||
WorldSave.getCurrentSave().clearChanges();
|
||||
WorldSave.getCurrentSave().getWorld().generateNew(0);
|
||||
if (difficulty != null)
|
||||
Current.player().updateDifficulty(Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]);
|
||||
Current.player().setWorldPosY((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosY * WorldSave.getCurrentSave().getWorld().getData().height * WorldSave.getCurrentSave().getWorld().getTileSize()));
|
||||
Current.player().setWorldPosX((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosX * WorldSave.getCurrentSave().getWorld().getData().width * WorldSave.getCurrentSave().getWorld().getTileSize()));
|
||||
Current.player().getQuests().clear();
|
||||
Current.player().resetQuestFlags();
|
||||
Current.player().setCharacterFlag("newGamePlus", 1);
|
||||
AdventurePlayer.current().addQuest("28");
|
||||
WorldStage.getInstance().enterSpawnPOI();
|
||||
SoundSystem.instance.changeBackgroundTrack();
|
||||
Forge.switchScene(GameScene.instance());
|
||||
if (WorldSave.getCurrentSave().getWorld().generateNew(0)) {
|
||||
if (difficulty != null)
|
||||
Current.player().updateDifficulty(Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]);
|
||||
Current.player().setWorldPosY((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosY * WorldSave.getCurrentSave().getWorld().getData().height * WorldSave.getCurrentSave().getWorld().getTileSize()));
|
||||
Current.player().setWorldPosX((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosX * WorldSave.getCurrentSave().getWorld().getData().width * WorldSave.getCurrentSave().getWorld().getTileSize()));
|
||||
Current.player().getQuests().clear();
|
||||
Current.player().resetQuestFlags();
|
||||
Current.player().setCharacterFlag("newGamePlus", 1);
|
||||
AdventurePlayer.current().addQuest("28");
|
||||
WorldStage.getInstance().enterSpawnPOI();
|
||||
SoundSystem.instance.changeBackgroundTrack();
|
||||
Forge.switchScene(GameScene.instance());
|
||||
} else {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
} else {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
|
||||
@@ -19,16 +19,23 @@ public class ColorMap
|
||||
}
|
||||
|
||||
public ColorMap(FileHandle file) {
|
||||
Pixmap pdata=new Pixmap(file);
|
||||
width=pdata.getWidth();
|
||||
height=pdata.getHeight();
|
||||
data=new Color[width*height];
|
||||
for(int y=0;y<height;y++)
|
||||
for(int x=0;x<width;x++)
|
||||
{
|
||||
data[x+y*width]=new Color(pdata.getPixel(x,y));
|
||||
}
|
||||
pdata.dispose();
|
||||
if (file.exists()) {
|
||||
Pixmap pdata=new Pixmap(file);
|
||||
width=pdata.getWidth();
|
||||
height=pdata.getHeight();
|
||||
data=new Color[width*height];
|
||||
for(int y=0;y<height;y++)
|
||||
for(int x=0;x<width;x++)
|
||||
{
|
||||
data[x+y*width]=new Color(pdata.getPixel(x,y));
|
||||
}
|
||||
pdata.dispose();
|
||||
} else {
|
||||
width = 0;
|
||||
height = 0;
|
||||
data = new Color[0];
|
||||
System.err.println("Cannot find file for ColorMap: " + file.path());
|
||||
}
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import forge.gui.GuiBase;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Class that will create the world from the configuration
|
||||
@@ -289,502 +290,522 @@ public class World implements Disposable, SaveFileContent {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public World generateNew(long seed) {
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(true);
|
||||
final long[] currentTime = {System.currentTimeMillis()};
|
||||
long startTime = System.currentTimeMillis();
|
||||
public boolean generateNew(long seed) {
|
||||
try {
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(true);
|
||||
final long[] currentTime = {System.currentTimeMillis()};
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
loadWorldData();
|
||||
loadWorldData();
|
||||
//////////////////
|
||||
///////// initialize
|
||||
//////////////////
|
||||
|
||||
if (seed == 0) {
|
||||
seed = random.nextLong();
|
||||
}
|
||||
this.seed = seed;
|
||||
random.setSeed(seed);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(seed);
|
||||
|
||||
float noiseZoom = data.noiseZoomBiome;
|
||||
width = data.width;
|
||||
height = data.height;
|
||||
//save at all data
|
||||
biomeMap = new long[width][height];
|
||||
terrainMap = new int[width][height];
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
biomeMap[x][y] = 0;
|
||||
terrainMap[x][y] = 0;
|
||||
if (seed == 0) {
|
||||
seed = random.nextLong();
|
||||
}
|
||||
}
|
||||
this.seed = seed;
|
||||
random.setSeed(seed);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(seed);
|
||||
|
||||
final int[] biomeIndex = {-1};
|
||||
currentTime[0] = measureGenerationTime("loading data", currentTime[0]);
|
||||
HashMap<BiomeStructureData, BiomeStructure> structureDataMap = new HashMap<>();
|
||||
float noiseZoom = data.noiseZoomBiome;
|
||||
width = data.width;
|
||||
height = data.height;
|
||||
//save at all data
|
||||
biomeMap = new long[width][height];
|
||||
terrainMap = new int[width][height];
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
biomeMap[x][y] = 0;
|
||||
terrainMap[x][y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
final int[] biomeIndex = {-1};
|
||||
currentTime[0] = measureGenerationTime("loading data", currentTime[0]);
|
||||
HashMap<BiomeStructureData, BiomeStructure> structureDataMap = new HashMap<>();
|
||||
|
||||
//////////////////
|
||||
///////// calculation structure position with wavefunctioncollapse
|
||||
//////////////////
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
if (biome.structures != null) {
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
int biomeHeight = (int) Math.round(biome.height * (double) height);
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
long localSeed = seed;
|
||||
long threadStartTime = System.currentTimeMillis();
|
||||
BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight);
|
||||
structure.initialize();
|
||||
structureDataMap.put(data, structure);
|
||||
measureGenerationTime("wavefunctioncollapse " + data.sourcePath, threadStartTime);
|
||||
List<CompletableFuture<Long>> futures = new ArrayList<>();
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
if (biome.structures != null) {
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
int biomeHeight = (int) Math.round(biome.height * (double) height);
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
long localSeed = seed;
|
||||
futures.add(CompletableFuture.supplyAsync(()-> {
|
||||
long threadStartTime = System.currentTimeMillis();
|
||||
BiomeStructure structure = new BiomeStructure(data, localSeed, biomeWidth, biomeHeight);
|
||||
structure.initialize();
|
||||
structureDataMap.put(data, structure);
|
||||
return measureGenerationTime("wavefunctioncollapse " + data.sourcePath, threadStartTime);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]);
|
||||
CompletableFuture.allOf(futuresArray).join();
|
||||
futures.clear();
|
||||
|
||||
//////////////////
|
||||
///////// calculation each biome position based on noise and radius
|
||||
//////////////////
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
|
||||
biomeIndex[0]++;
|
||||
int biomeXStart = (int) Math.round(biome.startPointX * (double) width);
|
||||
int biomeYStart = (int) Math.round(biome.startPointY * (double) height);
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
int biomeHeight = (int) Math.round(biome.height * (double) height);
|
||||
biomeIndex[0]++;
|
||||
int biomeXStart = (int) Math.round(biome.startPointX * (double) width);
|
||||
int biomeYStart = (int) Math.round(biome.startPointY * (double) height);
|
||||
int biomeWidth = (int) Math.round(biome.width * (double) width);
|
||||
int biomeHeight = (int) Math.round(biome.height * (double) height);
|
||||
|
||||
int beginX = Math.max(biomeXStart - biomeWidth / 2, 0);
|
||||
int beginY = Math.max(biomeYStart - biomeHeight / 2, 0);
|
||||
int endX = Math.min(biomeXStart + biomeWidth / 2, width);
|
||||
int endY = Math.min(biomeYStart + biomeHeight / 2, height);
|
||||
if (biome.width == 1.0 && biome.height == 1.0) {
|
||||
beginX = 0;
|
||||
beginY = 0;
|
||||
endX = width;
|
||||
endY = height;
|
||||
}
|
||||
for (int x = beginX; x < endX; x++) {
|
||||
for (int y = beginY; y < endY; y++) {
|
||||
//value 0-1 based on noise
|
||||
float noiseValue = ((float) noise.eval(x / (float) width * noiseZoom, y / (float) height * noiseZoom) + 1) / 2f;
|
||||
noiseValue *= biome.noiseWeight;
|
||||
//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);
|
||||
distanceValue *= biome.distWeight;
|
||||
if (noiseValue + distanceValue < 1.0 || biome.invertHeight && (1 - noiseValue) + distanceValue < 1.0) {
|
||||
Color color = biome.GetColor();
|
||||
float[] hsv = new float[3];
|
||||
color.toHsv(hsv);
|
||||
int count = (int) ((noiseValue - 0.5) * 10 / 4);
|
||||
//hsv[2]+=(count*0.2);
|
||||
biomeMap[x][y] |= (1L << biomeIndex[0]);
|
||||
int terrainCounter = 1;
|
||||
terrainMap[x][y] = 0;
|
||||
if (biome.terrain != null) {
|
||||
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) {
|
||||
terrainMap[x][y] = terrainCounter;
|
||||
//pix.fillRectangle(x*data.miniMapTileSize, y*data.miniMapTileSize,data.miniMapTileSize,data.miniMapTileSize);
|
||||
}
|
||||
terrainCounter++;
|
||||
}
|
||||
}
|
||||
if (biome.collision)
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
if (biome.structures != null) {
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
while (!structureDataMap.containsKey(data)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
int beginX = Math.max(biomeXStart - biomeWidth / 2, 0);
|
||||
int beginY = Math.max(biomeYStart - biomeHeight / 2, 0);
|
||||
int endX = Math.min(biomeXStart + biomeWidth / 2, width);
|
||||
int endY = Math.min(biomeYStart + biomeHeight / 2, height);
|
||||
if (biome.width == 1.0 && biome.height == 1.0) {
|
||||
beginX = 0;
|
||||
beginY = 0;
|
||||
endX = width;
|
||||
endY = height;
|
||||
}
|
||||
for (int x = beginX; x < endX; x++) {
|
||||
for (int y = beginY; y < endY; y++) {
|
||||
//value 0-1 based on noise
|
||||
float noiseValue = ((float) noise.eval(x / (float) width * noiseZoom, y / (float) height * noiseZoom) + 1) / 2f;
|
||||
noiseValue *= biome.noiseWeight;
|
||||
//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);
|
||||
distanceValue *= biome.distWeight;
|
||||
if (noiseValue + distanceValue < 1.0 || biome.invertHeight && (1 - noiseValue) + distanceValue < 1.0) {
|
||||
Color color = biome.GetColor();
|
||||
float[] hsv = new float[3];
|
||||
color.toHsv(hsv);
|
||||
int count = (int) ((noiseValue - 0.5) * 10 / 4);
|
||||
//hsv[2]+=(count*0.2);
|
||||
biomeMap[x][y] |= (1L << biomeIndex[0]);
|
||||
int terrainCounter = 1;
|
||||
terrainMap[x][y] = 0;
|
||||
if (biome.terrain != null) {
|
||||
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) {
|
||||
terrainMap[x][y] = terrainCounter;
|
||||
//pix.fillRectangle(x*data.miniMapTileSize, y*data.miniMapTileSize,data.miniMapTileSize,data.miniMapTileSize);
|
||||
}
|
||||
terrainCounter++;
|
||||
}
|
||||
}
|
||||
if (biome.collision)
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
if (biome.structures != null) {
|
||||
for (BiomeStructureData data : biome.structures) {
|
||||
while (!structureDataMap.containsKey(data)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
BiomeStructure structure = structureDataMap.get(data);
|
||||
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));
|
||||
BiomeStructure structure = structureDataMap.get(data);
|
||||
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 structureIndex = structure.objectID(structureXStart, structureYStart);
|
||||
if (structureIndex >= 0) {
|
||||
int structureIndex = structure.objectID(structureXStart, structureYStart);
|
||||
if (structureIndex >= 0) {
|
||||
|
||||
terrainMap[x][y] = terrainCounter + structureIndex;
|
||||
if (structure.collision(structureXStart, structureYStart))
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
terrainMap[x][y] |= isStructureBit;
|
||||
terrainMap[x][y] = terrainCounter + structureIndex;
|
||||
if (structure.collision(structureXStart, structureYStart))
|
||||
terrainMap[x][y] |= collisionBit;
|
||||
terrainMap[x][y] |= isStructureBit;
|
||||
|
||||
}
|
||||
|
||||
terrainCounter += structure.structureObjectCount();
|
||||
}
|
||||
|
||||
terrainCounter += structure.structureObjectCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("biomes in total", currentTime[0]);
|
||||
currentTime[0] = measureGenerationTime("biomes in total", currentTime[0]);
|
||||
|
||||
//////////////////
|
||||
///////// set poi placement
|
||||
//////////////////
|
||||
List<PointOfInterest> towns = new ArrayList<>();
|
||||
List<PointOfInterest> notTowns = new ArrayList<>();
|
||||
List<Rectangle> otherPoints = new ArrayList<>();
|
||||
List<PointOfInterest> towns = new ArrayList<>();
|
||||
List<PointOfInterest> notTowns = new ArrayList<>();
|
||||
List<Rectangle> otherPoints = new ArrayList<>();
|
||||
|
||||
TextureAtlas mapMarker = Config.instance().getAtlas(Paths.MAP_MARKER);
|
||||
TextureData texture = mapMarker.getTextures().first().getTextureData();
|
||||
if (!texture.isPrepared())
|
||||
texture.prepare();
|
||||
Pixmap mapMarkerPixmap = texture.consumePixmap();
|
||||
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));
|
||||
boolean running = true;
|
||||
here:
|
||||
while (running) {
|
||||
mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(), data.height / getChunkSize());
|
||||
int biomeIndex2 = -1;
|
||||
running = false;
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
biomeIndex2++;
|
||||
for (PointOfInterestData poi : biome.getPointsOfInterest()) {
|
||||
for (int i = 0; i < poi.count; i++) {
|
||||
for (int counter = 0; counter < 500; counter++)//tries 500 times to find a free point
|
||||
{
|
||||
float radius = (float) Math.sqrt(((random.nextDouble()) / 2 * poi.radiusFactor));
|
||||
float theta = (float) (random.nextDouble() * 2 * Math.PI);
|
||||
float x = (float) (radius * Math.cos(theta));
|
||||
x *= (biome.width * width / 2);
|
||||
x += (biome.startPointX * width);
|
||||
float y = (float) (radius * Math.sin(theta));
|
||||
y *= (biome.height * height / 2);
|
||||
y += (height - (biome.startPointY * height));
|
||||
TextureAtlas mapMarker = Config.instance().getAtlas(Paths.MAP_MARKER);
|
||||
TextureData texture = mapMarker.getTextures().first().getTextureData();
|
||||
if (!texture.isPrepared())
|
||||
texture.prepare();
|
||||
Pixmap mapMarkerPixmap = texture.consumePixmap();
|
||||
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));
|
||||
boolean running = true;
|
||||
here:
|
||||
while (running) {
|
||||
mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(), data.height / getChunkSize());
|
||||
int biomeIndex2 = -1;
|
||||
running = false;
|
||||
for (BiomeData biome : data.GetBiomes()) {
|
||||
biomeIndex2++;
|
||||
for (PointOfInterestData poi : biome.getPointsOfInterest()) {
|
||||
for (int i = 0; i < poi.count; i++) {
|
||||
for (int counter = 0; counter < 500; counter++)//tries 500 times to find a free point
|
||||
{
|
||||
float radius = (float) Math.sqrt(((random.nextDouble()) / 2 * poi.radiusFactor));
|
||||
float theta = (float) (random.nextDouble() * 2 * Math.PI);
|
||||
float x = (float) (radius * Math.cos(theta));
|
||||
x *= (biome.width * width / 2);
|
||||
x += (biome.startPointX * width);
|
||||
float y = (float) (radius * Math.sin(theta));
|
||||
y *= (biome.height * height / 2);
|
||||
y += (height - (biome.startPointY * height));
|
||||
|
||||
y += (poi.offsetY * (biome.height * height));
|
||||
x += (poi.offsetX * (biome.width * width));
|
||||
y += (poi.offsetY * (biome.height * height));
|
||||
x += (poi.offsetX * (biome.width * width));
|
||||
|
||||
if ((int) x < 0 || (int) y <= 0 || (int) y >= height || (int) x >= width || biomeIndex2 != highestBiome(getBiome((int) x, (int) y))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
x *= data.tileSize;
|
||||
y *= data.tileSize;
|
||||
|
||||
boolean breakNextLoop = false;
|
||||
for (Rectangle rect : otherPoints) {
|
||||
if (rect.contains(x, y)) {
|
||||
breakNextLoop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (breakNextLoop) {
|
||||
boolean foundSolution = false;
|
||||
boolean noSolution = false;
|
||||
breakNextLoop = false;
|
||||
for (int xi = -1; xi < 2 && !foundSolution; xi++) {
|
||||
for (int yi = -1; yi < 2 && !foundSolution; yi++) {
|
||||
for (Rectangle rect : otherPoints) {
|
||||
if (rect.contains(x + xi * data.tileSize, y + yi * data.tileSize)) {
|
||||
noSolution = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!noSolution) {
|
||||
foundSolution = true;
|
||||
x = x + xi * data.tileSize;
|
||||
y = y + yi * data.tileSize;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundSolution) {
|
||||
if (counter == 499) {
|
||||
System.err.print("Can not place POI " + poi.name + "...Rerunning..\n");
|
||||
running = true;
|
||||
towns.clear();
|
||||
notTowns.clear();
|
||||
otherPoints.clear();
|
||||
clearTerrain((int) (data.width * data.playerStartPosX), (int) (data.height * data.playerStartPosY), 10);
|
||||
storedInfo.clear();
|
||||
continue here;
|
||||
}
|
||||
if ((int) x < 0 || (int) y <= 0 || (int) y >= height || (int) x >= width || biomeIndex2 != highestBiome(getBiome((int) x, (int) y))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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);
|
||||
clearTerrain((int) (x / data.tileSize), (int) (y / data.tileSize), 3);
|
||||
mapPoiIds.add(newPoint);
|
||||
|
||||
TextureAtlas.AtlasRegion marker = mapMarker.findRegion(poi.type);
|
||||
x *= data.tileSize;
|
||||
y *= data.tileSize;
|
||||
|
||||
if (marker != null) {
|
||||
int xInPixels = (int) ((x / data.tileSize) * data.miniMapTileSize);
|
||||
int yInPixels = (int) ((height - (y / data.tileSize)) * data.miniMapTileSize);
|
||||
xInPixels -= (marker.getRegionWidth() / 2);
|
||||
yInPixels -= (marker.getRegionHeight() / 2);
|
||||
drawPixmapLater(mapMarkerPixmap, marker.getRegionX(), marker.getRegionY(),
|
||||
marker.getRegionWidth(), marker.getRegionHeight(), xInPixels, yInPixels, marker.getRegionWidth(), marker.getRegionHeight());
|
||||
}
|
||||
|
||||
|
||||
if (poi.type != null && (poi.type.equals("town") || poi.type.equals("capital"))) {
|
||||
if (!newPoint.hasDisplayName()) {
|
||||
if (poi.displayName == null || poi.displayName.isEmpty()) {
|
||||
newPoint.setDisplayName(biome.getNewTownName());
|
||||
} else {
|
||||
newPoint.setDisplayName(poi.getDisplayName());
|
||||
boolean breakNextLoop = false;
|
||||
for (Rectangle rect : otherPoints) {
|
||||
if (rect.contains(x, y)) {
|
||||
breakNextLoop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
towns.add(newPoint);
|
||||
} else {
|
||||
notTowns.add(newPoint);
|
||||
if (breakNextLoop) {
|
||||
boolean foundSolution = false;
|
||||
boolean noSolution = false;
|
||||
breakNextLoop = false;
|
||||
for (int xi = -1; xi < 2 && !foundSolution; xi++) {
|
||||
for (int yi = -1; yi < 2 && !foundSolution; yi++) {
|
||||
for (Rectangle rect : otherPoints) {
|
||||
if (rect.contains(x + xi * data.tileSize, y + yi * data.tileSize)) {
|
||||
noSolution = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!noSolution) {
|
||||
foundSolution = true;
|
||||
x = x + xi * data.tileSize;
|
||||
y = y + yi * data.tileSize;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundSolution) {
|
||||
if (counter == 499) {
|
||||
System.err.print("Can not place POI " + poi.name + "...Rerunning..\n");
|
||||
running = true;
|
||||
towns.clear();
|
||||
notTowns.clear();
|
||||
otherPoints.clear();
|
||||
clearTerrain((int) (data.width * data.playerStartPosX), (int) (data.height * data.playerStartPosY), 10);
|
||||
storedInfo.clear();
|
||||
continue here;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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);
|
||||
clearTerrain((int) (x / data.tileSize), (int) (y / data.tileSize), 3);
|
||||
mapPoiIds.add(newPoint);
|
||||
|
||||
TextureAtlas.AtlasRegion marker = mapMarker.findRegion(poi.type);
|
||||
|
||||
if (marker != null) {
|
||||
int xInPixels = (int) ((x / data.tileSize) * data.miniMapTileSize);
|
||||
int yInPixels = (int) ((height - (y / data.tileSize)) * data.miniMapTileSize);
|
||||
xInPixels -= (marker.getRegionWidth() / 2);
|
||||
yInPixels -= (marker.getRegionHeight() / 2);
|
||||
drawPixmapLater(mapMarkerPixmap, marker.getRegionX(), marker.getRegionY(),
|
||||
marker.getRegionWidth(), marker.getRegionHeight(), xInPixels, yInPixels, marker.getRegionWidth(), marker.getRegionHeight());
|
||||
}
|
||||
|
||||
|
||||
if (poi.type != null && (poi.type.equals("town") || poi.type.equals("capital"))) {
|
||||
if (!newPoint.hasDisplayName()) {
|
||||
if (poi.displayName == null || poi.displayName.isEmpty()) {
|
||||
newPoint.setDisplayName(biome.getNewTownName());
|
||||
} else {
|
||||
newPoint.setDisplayName(poi.getDisplayName());
|
||||
}
|
||||
}
|
||||
towns.add(newPoint);
|
||||
} else {
|
||||
notTowns.add(newPoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("poi placement", currentTime[0]);
|
||||
currentTime[0] = measureGenerationTime("poi placement", currentTime[0]);
|
||||
|
||||
//////////////////
|
||||
///////// sort towns and build roads in between
|
||||
//////////////////
|
||||
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
|
||||
for (int i = 0; i < towns.size() - 1; i++) {
|
||||
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++) {
|
||||
|
||||
PointOfInterest current = towns.get(i);
|
||||
int smallestIndex = -1;
|
||||
int secondSmallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
for (int j = 0; j < towns.size(); j++) {
|
||||
PointOfInterest current = towns.get(i);
|
||||
int smallestIndex = -1;
|
||||
int secondSmallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
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;
|
||||
float dist = current.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist > data.maxRoadDistance)
|
||||
continue;
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
secondSmallestIndex = smallestIndex;
|
||||
smallestIndex = j;
|
||||
|
||||
}
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
float dist = current.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist > data.maxRoadDistance)
|
||||
usedEdges.add((long) i | ((long) smallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) smallestIndex));
|
||||
allSortedTowns.add(Pair.of(current, towns.get(smallestIndex)));
|
||||
|
||||
if (secondSmallestIndex < 0)
|
||||
continue;
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
secondSmallestIndex = smallestIndex;
|
||||
smallestIndex = j;
|
||||
|
||||
}
|
||||
usedEdges.add((long) i | ((long) secondSmallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) secondSmallestIndex));
|
||||
//allSortedTowns.add(Pair.of(current, towns.get(secondSmallestIndex)));
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
usedEdges.add((long) i | ((long) smallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) smallestIndex));
|
||||
allSortedTowns.add(Pair.of(current, towns.get(smallestIndex)));
|
||||
List<Pair<PointOfInterest, PointOfInterest>> allPOIPathsToNextTown = new ArrayList<>();
|
||||
for (int i = 0; i < notTowns.size() - 1; i++) {
|
||||
|
||||
if (secondSmallestIndex < 0)
|
||||
continue;
|
||||
usedEdges.add((long) i | ((long) secondSmallestIndex << 32));
|
||||
usedEdges.add((long) i << 32 | ((long) secondSmallestIndex));
|
||||
//allSortedTowns.add(Pair.of(current, towns.get(secondSmallestIndex)));
|
||||
}
|
||||
List<Pair<PointOfInterest, PointOfInterest>> allPOIPathsToNextTown = new ArrayList<>();
|
||||
for (int i = 0; i < notTowns.size() - 1; i++) {
|
||||
PointOfInterest poi = notTowns.get(i);
|
||||
int smallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
for (int j = 0; j < towns.size(); j++) {
|
||||
|
||||
PointOfInterest poi = notTowns.get(i);
|
||||
int smallestIndex = -1;
|
||||
float smallestDistance = Float.MAX_VALUE;
|
||||
for (int j = 0; j < towns.size(); j++) {
|
||||
|
||||
float dist = poi.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
smallestIndex = j;
|
||||
float dist = poi.getPosition().dst(towns.get(j).getPosition());
|
||||
if (dist < smallestDistance) {
|
||||
smallestDistance = dist;
|
||||
smallestIndex = j;
|
||||
|
||||
}
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
allPOIPathsToNextTown.add(Pair.of(poi, towns.get(smallestIndex)));
|
||||
}
|
||||
if (smallestIndex < 0)
|
||||
continue;
|
||||
allPOIPathsToNextTown.add(Pair.of(poi, towns.get(smallestIndex)));
|
||||
}
|
||||
biomeIndex[0]++;
|
||||
biomeIndex[0]++;
|
||||
|
||||
//reset terrain path to the next town
|
||||
for (Pair<PointOfInterest, PointOfInterest> poiToTown : allPOIPathsToNextTown) {
|
||||
//reset terrain path to the next town
|
||||
for (Pair<PointOfInterest, PointOfInterest> poiToTown : allPOIPathsToNextTown) {
|
||||
futures.add(CompletableFuture.supplyAsync(()-> {
|
||||
int startX = (int) poiToTown.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) poiToTown.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).y;
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
if ((terrainMap[startX][height - startY] & collisionBit) != 0)//clear terrain if it has collision
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
|
||||
int startX = (int) poiToTown.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) poiToTown.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) poiToTown.getValue().getTilePosition(data.tileSize).y;
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
if ((terrainMap[startX][height - startY] & collisionBit) != 0)//clear terrain if it has collision
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
}
|
||||
return 0l;
|
||||
}));
|
||||
}
|
||||
}
|
||||
futuresArray = futures.toArray(new CompletableFuture<?>[0]);
|
||||
CompletableFuture.allOf(futuresArray).join();
|
||||
futures.clear();
|
||||
for (Pair<PointOfInterest, PointOfInterest> townPair : allSortedTowns) {
|
||||
futures.add(CompletableFuture.supplyAsync(()-> {
|
||||
int startX = (int) townPair.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) townPair.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) townPair.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) townPair.getValue().getTilePosition(data.tileSize).y;
|
||||
for (int x = startX - 1; x < startX + 2; x++) {
|
||||
for (int y = startY - 1; y < startY + 2; y++) {
|
||||
if (x < 0 || y < 0 || x >= width || y >= height) continue;
|
||||
biomeMap[x][height - y - 1] |= (1L << biomeIndex[0]);
|
||||
terrainMap[x][height - y - 1] = 0;
|
||||
}
|
||||
}
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
biomeMap[startX][height - startY] |= (1L << biomeIndex[0]);
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
|
||||
for (Pair<PointOfInterest, PointOfInterest> townPair : allSortedTowns) {
|
||||
|
||||
int startX = (int) townPair.getKey().getTilePosition(data.tileSize).x;
|
||||
int startY = (int) townPair.getKey().getTilePosition(data.tileSize).y;
|
||||
int x1 = (int) townPair.getValue().getTilePosition(data.tileSize).x;
|
||||
int y1 = (int) townPair.getValue().getTilePosition(data.tileSize).y;
|
||||
for (int x = startX - 1; x < startX + 2; x++) {
|
||||
for (int y = startY - 1; y < startY + 2; y++) {
|
||||
if (x < 0 || y < 0 || x >= width || y >= height) continue;
|
||||
biomeMap[x][height - y - 1] |= (1L << biomeIndex[0]);
|
||||
terrainMap[x][height - y - 1] = 0;
|
||||
}
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
}
|
||||
return 0l;
|
||||
}));
|
||||
}
|
||||
int dx = Math.abs(x1 - startX);
|
||||
int dy = Math.abs(y1 - startY);
|
||||
int sx = startX < x1 ? 1 : -1;
|
||||
int sy = startY < y1 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
int e2;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
|
||||
biomeMap[startX][height - startY] |= (1L << biomeIndex[0]);
|
||||
terrainMap[startX][height - startY] = 0;
|
||||
|
||||
if (startX == x1 && startY == y1)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err = err - dy;
|
||||
startX = startX + sx;
|
||||
} else if (e2 < dx) {
|
||||
err = err + dx;
|
||||
startY = startY + sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("roads", currentTime[0]);
|
||||
futuresArray = futures.toArray(new CompletableFuture<?>[0]);
|
||||
CompletableFuture.allOf(futuresArray).join();
|
||||
futures.clear();
|
||||
currentTime[0] = measureGenerationTime("roads", currentTime[0]);
|
||||
|
||||
//////////////////
|
||||
///////// draw mini map
|
||||
//////////////////
|
||||
|
||||
Pixmap pix = new Pixmap(width * data.miniMapTileSize, height * data.miniMapTileSize, Pixmap.Format.RGBA8888);
|
||||
pix.setColor(1, 0, 0, 1);
|
||||
pix.fill();
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
if (highestBiome(biomeMap[x][y]) >= data.GetBiomes().size()) {
|
||||
Pixmap smallPixmap = createSmallPixmap(data.roadTileset.tilesetAtlas, data.roadTileset.tilesetName, 0);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
} else {
|
||||
|
||||
BiomeData biome = data.GetBiomes().get(highestBiome(biomeMap[x][y]));
|
||||
int terrainIndex = terrainMap[x][y] & ~terrainMask;
|
||||
if (terrainIndex > biome.terrain.length) {
|
||||
Pixmap smallPixmap = createSmallPixmap(biome.tilesetAtlas, biome.tilesetName, 0);
|
||||
Pixmap pix = new Pixmap(width * data.miniMapTileSize, height * data.miniMapTileSize, Pixmap.Format.RGBA8888);
|
||||
pix.setColor(1, 0, 0, 1);
|
||||
pix.fill();
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
if (highestBiome(biomeMap[x][y]) >= data.GetBiomes().size()) {
|
||||
Pixmap smallPixmap = createSmallPixmap(data.roadTileset.tilesetAtlas, data.roadTileset.tilesetName, 0);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
|
||||
terrainIndex -= biome.terrain.length;
|
||||
terrainIndex--;
|
||||
for (BiomeStructureData structData : biome.structures) {
|
||||
if (terrainIndex >= structData.mappingInfo.length) {
|
||||
terrainIndex -= structData.mappingInfo.length;
|
||||
continue;
|
||||
}
|
||||
smallPixmap = createSmallPixmap(structData.structureAtlasPath, structData.mappingInfo[terrainIndex].name, 0);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Pixmap smallPixmap = createSmallPixmap(biome.tilesetAtlas, biome.tilesetName, terrainIndex);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
|
||||
BiomeData biome = data.GetBiomes().get(highestBiome(biomeMap[x][y]));
|
||||
int terrainIndex = terrainMap[x][y] & ~terrainMask;
|
||||
if (terrainIndex > biome.terrain.length) {
|
||||
Pixmap smallPixmap = createSmallPixmap(biome.tilesetAtlas, biome.tilesetName, 0);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
|
||||
terrainIndex -= biome.terrain.length;
|
||||
terrainIndex--;
|
||||
for (BiomeStructureData structData : biome.structures) {
|
||||
if (terrainIndex >= structData.mappingInfo.length) {
|
||||
terrainIndex -= structData.mappingInfo.length;
|
||||
continue;
|
||||
}
|
||||
smallPixmap = createSmallPixmap(structData.structureAtlasPath, structData.mappingInfo[terrainIndex].name, 0);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Pixmap smallPixmap = createSmallPixmap(biome.tilesetAtlas, biome.tilesetName, terrainIndex);
|
||||
pix.drawPixmap(smallPixmap, x * data.miniMapTileSize, y * data.miniMapTileSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
for (Map.Entry<String, Pair<Pixmap, HashMap<String, Pixmap>>> entry : pixmapHash.entrySet()) {
|
||||
try {
|
||||
entry.getValue().getLeft().dispose();
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
for (Map.Entry<String, Pixmap> pairEntry : entry.getValue().getRight().entrySet()) {
|
||||
for (Map.Entry<String, Pair<Pixmap, HashMap<String, Pixmap>>> entry : pixmapHash.entrySet()) {
|
||||
try {
|
||||
pairEntry.getValue().dispose();
|
||||
entry.getValue().getLeft().dispose();
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
for (Map.Entry<String, Pixmap> pairEntry : entry.getValue().getRight().entrySet()) {
|
||||
try {
|
||||
pairEntry.getValue().dispose();
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pixmapHash.clear();
|
||||
try {
|
||||
drawPixmapNow(pix);
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("mini map", currentTime[0]);
|
||||
pixmapHash.clear();
|
||||
try {
|
||||
drawPixmapNow(pix);
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("mini map", currentTime[0]);
|
||||
|
||||
|
||||
//////////////////
|
||||
///////// distribute small rocks and trees across the map
|
||||
//////////////////
|
||||
mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize());
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int invertedHeight = height - y - 1;
|
||||
int currentBiome = highestBiome(biomeMap[x][invertedHeight]);
|
||||
if (currentBiome >= data.GetBiomes().size())
|
||||
continue;//roads
|
||||
if (isStructure(x, y))
|
||||
continue;
|
||||
BiomeData biome = data.GetBiomes().get(currentBiome);
|
||||
for (String name : biome.spriteNames) {
|
||||
BiomeSpriteData sprite = data.GetBiomeSprites().getSpriteData(name);
|
||||
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 (random.nextFloat() <= sprite.density) {
|
||||
String spriteKey = sprite.key();
|
||||
int key;
|
||||
if (!mapObjectIds.containsKey(spriteKey)) {
|
||||
mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize());
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int invertedHeight = height - y - 1;
|
||||
int currentBiome = highestBiome(biomeMap[x][invertedHeight]);
|
||||
if (currentBiome >= data.GetBiomes().size())
|
||||
continue;//roads
|
||||
if (isStructure(x, y))
|
||||
continue;
|
||||
BiomeData biome = data.GetBiomes().get(currentBiome);
|
||||
for (String name : biome.spriteNames) {
|
||||
BiomeSpriteData sprite = data.GetBiomeSprites().getSpriteData(name);
|
||||
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 (random.nextFloat() <= sprite.density) {
|
||||
String spriteKey = sprite.key();
|
||||
int key;
|
||||
if (!mapObjectIds.containsKey(spriteKey)) {
|
||||
|
||||
key = mapObjectIds.put(sprite.key(), sprite, data.GetBiomeSprites());
|
||||
} else {
|
||||
key = mapObjectIds.intKey(spriteKey);
|
||||
key = mapObjectIds.put(sprite.key(), sprite, data.GetBiomeSprites());
|
||||
} else {
|
||||
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));
|
||||
break;//only on sprite per point
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mapMarkerPixmap.dispose();
|
||||
biomeImage = pix;
|
||||
measureGenerationTime("sprites", currentTime[0]);
|
||||
System.out.println("Generating world took :\t\t" + ((System.currentTimeMillis() - startTime) / 1000f) + " s");
|
||||
WorldStage.getInstance().clearCache();
|
||||
mapMarkerPixmap.dispose();
|
||||
biomeImage = pix;
|
||||
measureGenerationTime("sprites", currentTime[0]);
|
||||
System.out.println("Generating world took :\t\t" + ((System.currentTimeMillis() - startTime) / 1000f) + " s");
|
||||
WorldStage.getInstance().clearCache();
|
||||
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(false);
|
||||
return this;
|
||||
if (GuiBase.isAndroid())
|
||||
GuiBase.getInterface().preventSystemSleep(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HashMap<String, Pair<Pixmap, HashMap<String, Pixmap>>> pixmapHash = new HashMap<>();
|
||||
|
||||
@@ -79,7 +79,8 @@ public class WorldSave {
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Generating New World");
|
||||
currentSave.world.generateNew(0);
|
||||
if (!currentSave.world.generateNew(0))
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSave.onLoadList.emit();
|
||||
|
||||
@@ -3444,4 +3444,17 @@ lblRelease=Freigeben
|
||||
lblSnapshot=Schnappschuss
|
||||
lblNewSnapshotVersion=NEU FORGE-{0}!
|
||||
cbSnapshotUpdate=Überprüfen Sie Snapshot-Updates beim Start.
|
||||
nlSnapshotUpdate=Wenn diese Option aktiviert ist, werden Snapshot-Updates beim Start automatisch überprüft und die Benachrichtigung in der Titelleiste angezeigt.
|
||||
nlSnapshotUpdate=Wenn diese Option aktiviert ist, werden Snapshot-Updates beim Start automatisch überprüft und die Benachrichtigung in der Titelleiste angezeigt.
|
||||
lblAddCommander=Satz
|
||||
lblaspartnercommander=als Partnerkommandant
|
||||
lblfromattractiondeck=vom Attraktionsdeck
|
||||
lbltoattractiondeck=zum Attraktionsdeck
|
||||
lblAddDeckSection=Variantenabschnitt hinzufügen...
|
||||
lblAddDeckSectionSelect=Wählen Sie den Abschnitt zum Hinzufügen aus
|
||||
lblFrom=aus
|
||||
lblAttractions=Attraktionen
|
||||
lblConspiracies=Verschwörungen
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=Wählen Sie die Reihenfolge der Karten aus, die in den Attraktionsstapel gelegt werden sollen
|
||||
lblAttractionRollResult={0} gewürfelt, um ihre Attraktionen zu besuchen. Ergebnis: {1}.
|
||||
lblAttractionDeckZone=Attraktionsdeck
|
||||
lblLights=Lichter
|
||||
@@ -3458,4 +3458,11 @@ lblRelease=Liberar
|
||||
lblSnapshot=Instantánea
|
||||
lblNewSnapshotVersion=NUEVO FORGE-{0}!
|
||||
cbSnapshotUpdate=Verifique las actualizaciones de instantáneas al inicio.
|
||||
nlSnapshotUpdate=Cuando está habilitado, verifica automáticamente las actualizaciones de instantáneas al inicio y muestra la notificación en la barra de título.
|
||||
nlSnapshotUpdate=Cuando está habilitado, verifica automáticamente las actualizaciones de instantáneas al inicio y muestra la notificación en la barra de título.
|
||||
lblaspartnercommander=como comandante compañero
|
||||
lblfromattractiondeck=desde la plataforma de atracción
|
||||
lbltoattractiondeck=a la plataforma de atracción
|
||||
lblFrom=de
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=Elige el orden de las cartas para colocarlas en el mazo de atracciones.
|
||||
lblAttractionRollResult={0} rodó para visitar sus atracciones. Resultado: {1}.
|
||||
lblLights=Luces
|
||||
@@ -3452,4 +3452,17 @@ lblRelease=Libérer
|
||||
lblSnapshot=Instantané
|
||||
lblNewSnapshotVersion=NOUVEAU FORGE–{0}!
|
||||
cbSnapshotUpdate=Vérifiez les mises à jour des instantanés au démarrage.
|
||||
nlSnapshotUpdate=Lorsqu'il est activé, vérifie automatiquement les mises à jour des instantanés au démarrage et affiche la notification sur la barre de titre.
|
||||
nlSnapshotUpdate=Lorsqu'il est activé, vérifie automatiquement les mises à jour des instantanés au démarrage et affiche la notification sur la barre de titre.
|
||||
lblAddCommander=Ensemble
|
||||
lblaspartnercommander=en tant que commandant partenaire
|
||||
lblfromattractiondeck=depuis le pont d'attraction
|
||||
lbltoattractiondeck=au pont d'attraction
|
||||
lblAddDeckSection=Ajouter une section de variante...
|
||||
lblAddDeckSectionSelect=Sélectionnez la section à ajouter
|
||||
lblFrom=depuis
|
||||
lblAttractions=Attractions
|
||||
lblConspiracies=Conspirations
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=Choisissez l'ordre des cartes à mettre dans le jeu d'attraction
|
||||
lblAttractionRollResult={0} ont lancé un jet pour visiter leurs attractions. Résultat: {1}.
|
||||
lblAttractionDeckZone=pont d'attraction
|
||||
lblLights=Lumières
|
||||
@@ -3450,4 +3450,17 @@ lblRelease=Pubblicazione
|
||||
lblSnapshot=Istantanea
|
||||
lblNewSnapshotVersion=NUOVO FORGE-{0}!
|
||||
cbSnapshotUpdate=Controlla gli aggiornamenti delle istantanee all'avvio.
|
||||
nlSnapshotUpdate=Se abilitato, controlla automaticamente gli aggiornamenti delle istantanee all'avvio e visualizza la notifica sulla barra del titolo.
|
||||
nlSnapshotUpdate=Se abilitato, controlla automaticamente gli aggiornamenti delle istantanee all'avvio e visualizza la notifica sulla barra del titolo.
|
||||
lblAddCommander=Impostato
|
||||
lblaspartnercommander=come comandante partner
|
||||
lblfromattractiondeck=dal ponte delle attrazioni
|
||||
lbltoattractiondeck=al ponte delle attrazioni
|
||||
lblAddDeckSection=Aggiungi sezione variante...
|
||||
lblAddDeckSectionSelect=Seleziona la sezione da aggiungere
|
||||
lblFrom=da
|
||||
lblAttractions=Attrazioni
|
||||
lblConspiracies=Cospirazioni
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=Scegli l'ordine delle carte da inserire nel mazzo delle attrazioni
|
||||
lblAttractionRollResult={0} ha rotolato per visitare le sue attrazioni. Risultato: {1}.
|
||||
lblAttractionDeckZone=attrazione
|
||||
lblLights=Luci
|
||||
@@ -3446,4 +3446,17 @@ lblRelease=リリース
|
||||
lblSnapshot=スナップショット
|
||||
lblNewSnapshotVersion=新しい FORGE-{0}!
|
||||
cbSnapshotUpdate=起動時にスナップショットの更新を確認します。
|
||||
nlSnapshotUpdate=有効にすると、起動時にスナップショットの更新が自動的にチェックされ、タイトル バーに通知が表示されます。
|
||||
nlSnapshotUpdate=有効にすると、起動時にスナップショットの更新が自動的にチェックされ、タイトル バーに通知が表示されます。
|
||||
lblAddCommander=セット
|
||||
lblaspartnercommander=パートナー指揮官として
|
||||
lblfromattractiondeck=アトラクションデッキから
|
||||
lbltoattractiondeck=アトラクションデッキへ
|
||||
lblAddDeckSection=バリアント セクションを追加...
|
||||
lblAddDeckSectionSelect=追加するセクションを選択してください
|
||||
lblFrom=から
|
||||
lblAttractions=アトラクション
|
||||
lblConspiracies=陰謀
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=アトラクションデッキに入れるカードの順番を選択してください
|
||||
lblAttractionRollResult={0} はアトラクションを訪れるために転がりました。結果: {1}。
|
||||
lblAttractionDeckZone=アトラクションデッキ
|
||||
lblLights=ライト
|
||||
@@ -3536,4 +3536,17 @@ lblRelease=Liberar
|
||||
lblSnapshot=Instantâneo
|
||||
lblNewSnapshotVersion=NOVO FORGE-{0}!
|
||||
cbSnapshotUpdate=Verifique as atualizações de instantâneos na inicialização.
|
||||
nlSnapshotUpdate=Quando ativado, verifica automaticamente as atualizações do snapshot na inicialização e exibe a notificação na barra de título.
|
||||
nlSnapshotUpdate=Quando ativado, verifica automaticamente as atualizações do snapshot na inicialização e exibe a notificação na barra de título.
|
||||
lblAddCommander=Definir
|
||||
lblaspartnercommander=como comandante parceiro
|
||||
lblfromattractiondeck=do deck de atração
|
||||
lbltoattractiondeck=para o deck de atração
|
||||
lblAddDeckSection=Adicionar seção de variante...
|
||||
lblAddDeckSectionSelect=Selecione a seção a ser adicionada
|
||||
lblFrom=de
|
||||
lblAttractions=Atrações
|
||||
lblConspiracies=Conspirações
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=Escolha a ordem das cartas para colocar no baralho de atração
|
||||
lblAttractionRollResult={0} rolou para visitar suas atrações. Resultado: {1}.
|
||||
lblAttractionDeckZone=deck de atração
|
||||
lblLights=Luzes
|
||||
@@ -3437,4 +3437,17 @@ lblRelease=发布
|
||||
lblSnapshot=快照
|
||||
lblNewSnapshotVersion=新 FORGE-{0}!
|
||||
cbSnapshotUpdate=启动时检查快照更新。
|
||||
nlSnapshotUpdate=启用后,启动时自动检查快照更新并在标题栏上显示通知。
|
||||
nlSnapshotUpdate=启用后,启动时自动检查快照更新并在标题栏上显示通知。
|
||||
lblAddCommander=放
|
||||
lblaspartnercommander=作为伙伴指挥官
|
||||
lblfromattractiondeck=从景点甲板
|
||||
lbltoattractiondeck=到景点甲板
|
||||
lblAddDeckSection=添加变体部分...
|
||||
lblAddDeckSectionSelect=选择要添加的部分
|
||||
lblFrom=从
|
||||
lblAttractions=景点
|
||||
lblConspiracies=阴谋
|
||||
lblChooseOrderCardsPutIntoAttractionDeck=选择放入景点牌组的卡片顺序
|
||||
lblAttractionRollResult={0} 滚动访问他们的景点。结果:{1}。
|
||||
lblAttractionDeckZone=吸引力甲板
|
||||
lblLights=灯
|
||||
Reference in New Issue
Block a user