2018-05-29 19:01:22 +00:00
package com.unciv
2018-07-20 12:58:03 +00:00
import com.badlogic.gdx.math.Vector2
2018-05-29 19:01:22 +00:00
import com.unciv.logic.GameInfo
import com.unciv.logic.civilization.CivilizationInfo
2018-12-18 16:57:13 +00:00
import com.unciv.logic.civilization.PlayerType
2018-11-26 17:50:58 +00:00
import com.unciv.logic.map.TileInfo
2018-05-29 19:01:22 +00:00
import com.unciv.logic.map.TileMap
import com.unciv.models.gamebasics.GameBasics
2018-08-24 09:28:27 +00:00
import com.unciv.ui.NewGameScreen
2018-05-29 19:01:22 +00:00
import com.unciv.ui.utils.getRandom
2018-11-26 17:50:58 +00:00
import java.util.*
2018-05-29 19:01:22 +00:00
2018-12-04 21:21:57 +00:00
class GameStarter {
2018-08-24 09:28:27 +00:00
fun startNewGame ( newGameParameters : NewGameScreen . NewGameParameters ) : GameInfo {
2018-05-29 19:01:22 +00:00
val gameInfo = GameInfo ( )
2018-10-12 11:19:05 +00:00
gameInfo . tileMap = TileMap ( newGameParameters . mapRadius , newGameParameters . mapType )
2018-05-31 14:23:46 +00:00
gameInfo . tileMap . gameInfo = gameInfo // need to set this transient before placing units in the map
2018-11-26 17:50:58 +00:00
val startingLocations = getStartingLocations ( newGameParameters . numberOfEnemies + 1 , gameInfo . tileMap )
2018-07-18 15:45:37 +00:00
2018-05-29 19:01:22 +00:00
2018-11-17 19:02:42 +00:00
val playerCiv = CivilizationInfo ( newGameParameters . nation )
2018-12-18 17:26:56 +00:00
gameInfo . difficulty = newGameParameters . difficulty
2018-12-18 16:57:13 +00:00
playerCiv . playerType = PlayerType . Human
2018-07-25 19:56:25 +00:00
gameInfo . civilizations . add ( playerCiv ) // first one is player civ
2018-07-18 15:45:37 +00:00
2018-05-29 19:01:22 +00:00
val barbarianCivilization = CivilizationInfo ( )
gameInfo . civilizations . add ( barbarianCivilization ) // second is barbarian civ
2018-08-24 09:28:27 +00:00
for ( nationName in GameBasics . Nations . keys . filterNot { it == " Barbarians " || it == newGameParameters . nation } . shuffled ( )
. take ( newGameParameters . numberOfEnemies ) ) {
2018-11-17 19:02:42 +00:00
val civ = CivilizationInfo ( nationName )
2018-07-25 19:56:25 +00:00
gameInfo . civilizations . add ( civ )
2018-05-29 19:01:22 +00:00
}
2018-08-22 10:30:37 +00:00
2018-05-29 19:01:22 +00:00
barbarianCivilization . civName = " Barbarians "
gameInfo . setTransients ( ) // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set
2018-12-24 12:01:32 +00:00
for ( civInfo in gameInfo . civilizations . filter { ! it . isBarbarianCivilization ( ) && ! it . isPlayerCivilization ( ) } ) {
for ( tech in gameInfo . getDifficulty ( ) . aiFreeTechs )
civInfo . tech . addTechnology ( tech )
}
2018-08-23 05:43:14 +00:00
// 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!
2018-08-22 10:30:37 +00:00
2018-11-26 17:50:58 +00:00
for ( civ in gameInfo . civilizations . filter { ! it . isBarbarianCivilization ( ) } ) {
val startingLocation = startingLocations . pop ( ) !!
2018-08-22 10:30:37 +00:00
2018-11-26 17:50:58 +00:00
civ . placeUnitNearTile ( startingLocation . position , " Settler " )
civ . placeUnitNearTile ( startingLocation . position , " Warrior " )
civ . placeUnitNearTile ( startingLocation . position , " Scout " )
2018-08-22 10:30:37 +00:00
}
2018-05-29 19:01:22 +00:00
return gameInfo
}
2018-11-26 17:50:58 +00:00
fun getStartingLocations ( numberOfPlayers : Int , tileMap : TileMap ) : Stack < TileInfo > {
2018-11-30 08:21:44 +00:00
for ( minimumDistanceBetweenStartingLocations in 7 downTo 0 ) {
2018-11-26 17:50:58 +00:00
val freeTiles = tileMap . values
. filter { it . isLand ( ) && vectorIsWithinNTilesOfEdge ( it . position , 3 , tileMap ) }
. toMutableList ( )
val startingLocations = ArrayList < TileInfo > ( )
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 < TileInfo > ( )
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
}
2018-05-29 19:01:22 +00:00
}