From c6aecafe6b7226a1c549260c72fe09ddaf88c04c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sun, 3 Nov 2024 05:58:28 +0800 Subject: [PATCH] add missing translation, minor speedup generating map --- .../forge/adventure/scene/SaveLoadScene.java | 27 +- .../src/forge/adventure/world/ColorMap.java | 27 +- .../src/forge/adventure/world/World.java | 817 +++++++++--------- .../src/forge/adventure/world/WorldSave.java | 3 +- forge-gui/res/languages/de-DE.properties | 15 +- forge-gui/res/languages/es-ES.properties | 9 +- forge-gui/res/languages/fr-FR.properties | 15 +- forge-gui/res/languages/it-IT.properties | 15 +- forge-gui/res/languages/ja-JP.properties | 15 +- forge-gui/res/languages/pt-BR.properties | 15 +- forge-gui/res/languages/zh-CN.properties | 15 +- 11 files changed, 545 insertions(+), 428 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java index b93e41f7677..65fc3bd66bc 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java @@ -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(); } diff --git a/forge-gui-mobile/src/forge/adventure/world/ColorMap.java b/forge-gui-mobile/src/forge/adventure/world/ColorMap.java index eec74a70692..738fb706423 100644 --- a/forge-gui-mobile/src/forge/adventure/world/ColorMap.java +++ b/forge-gui-mobile/src/forge/adventure/world/ColorMap.java @@ -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 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 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> 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 towns = new ArrayList<>(); - List notTowns = new ArrayList<>(); - List otherPoints = new ArrayList<>(); + List towns = new ArrayList<>(); + List notTowns = new ArrayList<>(); + List 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> allSortedTowns = new ArrayList<>(); + List> allSortedTowns = new ArrayList<>(); - HashSet 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 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> 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> 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 poiToTown : allPOIPathsToNextTown) { + //reset terrain path to the next town + for (Pair 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 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 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>> entry : pixmapHash.entrySet()) { - try { - entry.getValue().getLeft().dispose(); - } catch (Exception e) { - //e.printStackTrace(); - } - for (Map.Entry pairEntry : entry.getValue().getRight().entrySet()) { + for (Map.Entry>> entry : pixmapHash.entrySet()) { try { - pairEntry.getValue().dispose(); + entry.getValue().getLeft().dispose(); } catch (Exception e) { //e.printStackTrace(); } + for (Map.Entry 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>> pixmapHash = new HashMap<>(); diff --git a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java index b765d571ae6..0b5d4a74706 100644 --- a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java +++ b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java @@ -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(); diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 326f0aca910..f93d295cf12 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -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. \ No newline at end of file +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 \ No newline at end of file diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 4c70418c04d..578fb95302b 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -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. \ No newline at end of file +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 \ No newline at end of file diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index 389cfba3d2f..4b6598e1a28 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -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. \ No newline at end of file +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 \ No newline at end of file diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index ff67d72094a..f2d6c6edb3f 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -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. \ No newline at end of file +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 \ No newline at end of file diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 0228a44dedf..875005021e8 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -3446,4 +3446,17 @@ lblRelease=リリース lblSnapshot=スナップショット lblNewSnapshotVersion=新しい FORGE-{0}! cbSnapshotUpdate=起動時にスナップショットの更新を確認します。 -nlSnapshotUpdate=有効にすると、起動時にスナップショットの更新が自動的にチェックされ、タイトル バーに通知が表示されます。 \ No newline at end of file +nlSnapshotUpdate=有効にすると、起動時にスナップショットの更新が自動的にチェックされ、タイトル バーに通知が表示されます。 +lblAddCommander=セット +lblaspartnercommander=パートナー指揮官として +lblfromattractiondeck=アトラクションデッキから +lbltoattractiondeck=アトラクションデッキへ +lblAddDeckSection=バリアント セクションを追加... +lblAddDeckSectionSelect=追加するセクションを選択してください +lblFrom=から +lblAttractions=アトラクション +lblConspiracies=陰謀 +lblChooseOrderCardsPutIntoAttractionDeck=アトラクションデッキに入れるカードの順番を選択してください +lblAttractionRollResult={0} はアトラクションを訪れるために転がりました。結果: {1}。 +lblAttractionDeckZone=アトラクションデッキ +lblLights=ライト \ No newline at end of file diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index aa5caa2a783..ecc81e7b118 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -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. \ No newline at end of file +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 \ No newline at end of file diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index e89bf5ee479..7981a598c18 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -3437,4 +3437,17 @@ lblRelease=发布 lblSnapshot=快照 lblNewSnapshotVersion=新 FORGE-{0}! cbSnapshotUpdate=启动时检查快照更新。 -nlSnapshotUpdate=启用后,启动时自动检查快照更新并在标题栏上显示通知。 \ No newline at end of file +nlSnapshotUpdate=启用后,启动时自动检查快照更新并在标题栏上显示通知。 +lblAddCommander=放 +lblaspartnercommander=作为伙伴指挥官 +lblfromattractiondeck=从景点甲板 +lbltoattractiondeck=到景点甲板 +lblAddDeckSection=添加变体部分... +lblAddDeckSectionSelect=选择要添加的部分 +lblFrom=从 +lblAttractions=景点 +lblConspiracies=阴谋 +lblChooseOrderCardsPutIntoAttractionDeck=选择放入景点牌组的卡片顺序 +lblAttractionRollResult={0} 滚动访问他们的景点。结果:{1}。 +lblAttractionDeckZone=吸引力甲板 +lblLights=灯 \ No newline at end of file