From 24ccd630dab8bb6e5740ec9c240ac2cd205e2078 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Mon, 26 Nov 2018 19:50:58 +0200 Subject: [PATCH] Can now select as many enemy civs as there are civilizations to assign to them Can now start the game with "Huge" maps, because "Large" wasn't big enough for everyone apparently -_- --- core/src/com/unciv/GameStarter.kt | 65 ++++++++++++++++---------- core/src/com/unciv/ui/NewGameScreen.kt | 3 +- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/core/src/com/unciv/GameStarter.kt b/core/src/com/unciv/GameStarter.kt index 61cc984913..7a5e97f410 100644 --- a/core/src/com/unciv/GameStarter.kt +++ b/core/src/com/unciv/GameStarter.kt @@ -3,10 +3,12 @@ package com.unciv import com.badlogic.gdx.math.Vector2 import com.unciv.logic.GameInfo import com.unciv.logic.civilization.CivilizationInfo +import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap import com.unciv.models.gamebasics.GameBasics import com.unciv.ui.NewGameScreen import com.unciv.ui.utils.getRandom +import java.util.* class GameStarter(){ fun startNewGame(newGameParameters: NewGameScreen.NewGameParameters): GameInfo { @@ -14,26 +16,13 @@ class GameStarter(){ gameInfo.tileMap = TileMap(newGameParameters.mapRadius, newGameParameters.mapType) gameInfo.tileMap.gameInfo = gameInfo // need to set this transient before placing units in the map + val startingLocations = getStartingLocations(newGameParameters.numberOfEnemies+1,gameInfo.tileMap) - fun vectorIsWithinNTilesOfEdge(vector: Vector2,n:Int): Boolean { - return vector.x < newGameParameters.mapRadius-n - && vector.x > n-newGameParameters.mapRadius - && vector.y < newGameParameters.mapRadius-n - && vector.y > n-newGameParameters.mapRadius - } - - val distanceAroundStartingPointNoOneElseWillStartIn = 5 - val freeTiles = gameInfo.tileMap.values - .filter { it.isLand() && vectorIsWithinNTilesOfEdge(it.position,3)} - .toMutableList() - val playerPosition = freeTiles.getRandom().position val playerCiv = CivilizationInfo(newGameParameters.nation) playerCiv.difficulty=newGameParameters.difficulty gameInfo.civilizations.add(playerCiv) // first one is player civ - freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(playerPosition, distanceAroundStartingPointNoOneElseWillStartIn )) - val barbarianCivilization = CivilizationInfo() gameInfo.civilizations.add(barbarianCivilization)// second is barbarian civ @@ -51,20 +40,46 @@ class GameStarter(){ // and only now do we add units for everyone, because otherwise both the gameInfo.setTransients() and the placeUnit will both add the unit to the civ's unit list! - for (civ in gameInfo.civilizations.toList().filter { !it.isBarbarianCivilization() }) { - if(freeTiles.isEmpty()){ - gameInfo.civilizations.remove(civ) - continue - } // we can't add any more civs. - val startingLocation = freeTiles.toList().getRandom().position + for (civ in gameInfo.civilizations.filter { !it.isBarbarianCivilization() }) { + val startingLocation = startingLocations.pop()!! - civ.placeUnitNearTile(startingLocation, "Settler") - civ.placeUnitNearTile(startingLocation, "Warrior") - civ.placeUnitNearTile(startingLocation, "Scout") - - freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(startingLocation, distanceAroundStartingPointNoOneElseWillStartIn )) + civ.placeUnitNearTile(startingLocation.position, "Settler") + civ.placeUnitNearTile(startingLocation.position, "Warrior") + civ.placeUnitNearTile(startingLocation.position, "Scout") } return gameInfo } + + fun getStartingLocations(numberOfPlayers:Int,tileMap: TileMap): Stack { + for(minimumDistanceBetweenStartingLocations in 7 downTo 1){ + val freeTiles = tileMap.values + .filter { it.isLand() && vectorIsWithinNTilesOfEdge(it.position,3,tileMap)} + .toMutableList() + + val startingLocations = ArrayList() + for(player in 0..numberOfPlayers){ + if(freeTiles.isEmpty()) break // we failed to get all the starting locations with this minimum distance + val randomLocation = freeTiles.getRandom() + startingLocations.add(randomLocation) + freeTiles.removeAll(tileMap.getTilesInDistance(randomLocation.position,minimumDistanceBetweenStartingLocations)) + } + if(startingLocations.size < numberOfPlayers) continue // let's try again with less minimum distance! + val stack = Stack() + stack.addAll(startingLocations) + return stack + } + throw Exception("Didn't manage to get starting locations even with distance of 1?") + } + + fun vectorIsWithinNTilesOfEdge(vector: Vector2,n:Int, tileMap: TileMap): Boolean { + val arrayXIndex = vector.x.toInt()-tileMap.leftX + val arrayYIndex = vector.y.toInt()-tileMap.bottomY + + return arrayXIndex < tileMap.tileMatrix.size-n + && arrayXIndex > n + && arrayYIndex < tileMap.tileMatrix[arrayXIndex].size-n + && arrayYIndex > n + } + } \ No newline at end of file diff --git a/core/src/com/unciv/ui/NewGameScreen.kt b/core/src/com/unciv/ui/NewGameScreen.kt index b47e150d58..d636fe4bbd 100644 --- a/core/src/com/unciv/ui/NewGameScreen.kt +++ b/core/src/com/unciv/ui/NewGameScreen.kt @@ -115,6 +115,7 @@ class NewGameScreen: PickerScreen(){ worldSizeToRadius["Small"] = 10 worldSizeToRadius["Medium"] = 20 worldSizeToRadius["Large"] = 30 + worldSizeToRadius["Huge"] = 40 val worldSizeSelectBox = TranslatedSelectBox(worldSizeToRadius.keys, "Medium", skin) worldSizeSelectBox.addListener(object : ChangeListener() { @@ -128,7 +129,7 @@ class NewGameScreen: PickerScreen(){ newGameOptionsTable.add("{Number of enemies}:".tr()) val enemiesSelectBox = SelectBox(skin) val enemiesArray = Array() - (1..5).forEach { enemiesArray.add(it) } + (1..GameBasics.Nations.size-1).forEach { enemiesArray.add(it) } enemiesSelectBox.items = enemiesArray enemiesSelectBox.selected = newGameParameters.numberOfEnemies