Preserve mod order in ruleset and game parameters
This commit is contained in:
parent
6fa22a92a1
commit
efc131c863
3 changed files with 49 additions and 50 deletions
|
@ -19,7 +19,7 @@ object GameStarter {
|
|||
gameInfo.gameParameters = newGameParameters
|
||||
val ruleset = RulesetCache.getComplexRuleset(newGameParameters.mods)
|
||||
|
||||
if(mapParameters.name != "")
|
||||
if (mapParameters.name != "")
|
||||
gameInfo.tileMap = MapSaver.loadMap(mapParameters.name)
|
||||
else gameInfo.tileMap = MapGenerator(ruleset).generateMap(mapParameters)
|
||||
gameInfo.tileMap.mapParameters = mapParameters
|
||||
|
@ -35,7 +35,7 @@ object GameStarter {
|
|||
gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set
|
||||
|
||||
// Add Civ Technologies
|
||||
for (civInfo in gameInfo.civilizations.filter {!it.isBarbarian()}) {
|
||||
for (civInfo in gameInfo.civilizations.filter { !it.isBarbarian() }) {
|
||||
|
||||
if (!civInfo.isPlayerCivilization())
|
||||
for (tech in gameInfo.getDifficulty().aiFreeTechs)
|
||||
|
@ -100,9 +100,9 @@ object GameStarter {
|
|||
gameInfo.tileMap)
|
||||
|
||||
// remove starting locations one we're done
|
||||
for(tile in gameInfo.tileMap.values){
|
||||
if(tile.improvement!=null && tile.improvement!!.startsWith("StartingLocation "))
|
||||
tile.improvement=null
|
||||
for (tile in gameInfo.tileMap.values) {
|
||||
if (tile.improvement != null && tile.improvement!!.startsWith("StartingLocation "))
|
||||
tile.improvement = null
|
||||
}
|
||||
|
||||
// For later starting eras, or for civs like Polynesia with a different Warrior, we need different starting units
|
||||
|
@ -131,42 +131,42 @@ object GameStarter {
|
|||
|
||||
}
|
||||
|
||||
private fun getStartingLocations(civs:List<CivilizationInfo>, tileMap: TileMap): HashMap<CivilizationInfo, TileInfo> {
|
||||
private fun getStartingLocations(civs: List<CivilizationInfo>, tileMap: TileMap): HashMap<CivilizationInfo, TileInfo> {
|
||||
var landTiles = tileMap.values
|
||||
.filter { it.isLand && !it.getBaseTerrain().impassable }
|
||||
|
||||
val landTilesInBigEnoughGroup = ArrayList<TileInfo>()
|
||||
while(landTiles.any()){
|
||||
val bfs = BFS(landTiles.random()){it.isLand && !it.getBaseTerrain().impassable}
|
||||
while (landTiles.any()) {
|
||||
val bfs = BFS(landTiles.random()) { it.isLand && !it.getBaseTerrain().impassable }
|
||||
bfs.stepToEnd()
|
||||
val tilesInGroup = bfs.tilesReached.keys
|
||||
landTiles = landTiles.filter { it !in tilesInGroup }
|
||||
if(tilesInGroup.size > 20) // is this a good number? I dunno, but it's easy enough to change later on
|
||||
if (tilesInGroup.size > 20) // is this a good number? I dunno, but it's easy enough to change later on
|
||||
landTilesInBigEnoughGroup.addAll(tilesInGroup)
|
||||
}
|
||||
|
||||
val tilesWithStartingLocations = tileMap.values
|
||||
.filter { it.improvement!=null && it.improvement!!.startsWith("StartingLocation ") }
|
||||
.filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") }
|
||||
|
||||
val civsOrderedByAvailableLocations = civs.sortedBy {civ ->
|
||||
val civsOrderedByAvailableLocations = civs.sortedBy { civ ->
|
||||
when {
|
||||
tilesWithStartingLocations.any { it.improvement=="StartingLocation "+civ.civName } -> 1 // harshest requirements
|
||||
tilesWithStartingLocations.any { it.improvement == "StartingLocation " + civ.civName } -> 1 // harshest requirements
|
||||
civ.nation.startBias.isNotEmpty() -> 2 // less harsh
|
||||
else -> 3
|
||||
} // no requirements
|
||||
}
|
||||
|
||||
for(minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size/3 downTo 0){
|
||||
for (minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size / 3 downTo 0) {
|
||||
val freeTiles = landTilesInBigEnoughGroup
|
||||
.filter { vectorIsAtLeastNTilesAwayFromEdge(it.position,minimumDistanceBetweenStartingLocations,tileMap)}
|
||||
.filter { vectorIsAtLeastNTilesAwayFromEdge(it.position, minimumDistanceBetweenStartingLocations, tileMap) }
|
||||
.toMutableList()
|
||||
|
||||
val startingLocations = HashMap<CivilizationInfo,TileInfo>()
|
||||
val startingLocations = HashMap<CivilizationInfo, TileInfo>()
|
||||
|
||||
for(civ in civsOrderedByAvailableLocations){
|
||||
var startingLocation:TileInfo
|
||||
val presetStartingLocation = tilesWithStartingLocations.firstOrNull { it.improvement=="StartingLocation "+civ.civName }
|
||||
if(presetStartingLocation!=null) startingLocation = presetStartingLocation
|
||||
for (civ in civsOrderedByAvailableLocations) {
|
||||
var startingLocation: TileInfo
|
||||
val presetStartingLocation = tilesWithStartingLocations.firstOrNull { it.improvement == "StartingLocation " + civ.civName }
|
||||
if (presetStartingLocation != null) startingLocation = presetStartingLocation
|
||||
else {
|
||||
if (freeTiles.isEmpty()) break // we failed to get all the starting tiles with this minimum distance
|
||||
var preferredTiles = freeTiles.toList()
|
||||
|
@ -182,21 +182,21 @@ object GameStarter {
|
|||
startingLocation = if (preferredTiles.isNotEmpty()) preferredTiles.random() else freeTiles.random()
|
||||
}
|
||||
startingLocations[civ] = startingLocation
|
||||
freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position,minimumDistanceBetweenStartingLocations))
|
||||
freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, minimumDistanceBetweenStartingLocations))
|
||||
}
|
||||
if(startingLocations.size < civs.size) continue // let's try again with less minimum distance!
|
||||
if (startingLocations.size < civs.size) continue // let's try again with less minimum distance!
|
||||
|
||||
return startingLocations
|
||||
}
|
||||
throw Exception("Didn't manage to get starting tiles even with distance of 1?")
|
||||
}
|
||||
|
||||
private fun vectorIsAtLeastNTilesAwayFromEdge(vector: Vector2, n:Int, tileMap: TileMap): Boolean {
|
||||
private fun vectorIsAtLeastNTilesAwayFromEdge(vector: Vector2, n: Int, tileMap: TileMap): Boolean {
|
||||
// Since all maps are HEXAGONAL, the easiest way of checking if a tile is n steps away from the
|
||||
// edge is checking the distance to the CENTER POINT
|
||||
// Can't believe we used a dumb way of calculating this before!
|
||||
val hexagonalRadius = -tileMap.leftX
|
||||
val distanceFromCenter = HexMath.getDistance(vector, Vector2.Zero)
|
||||
return hexagonalRadius-distanceFromCenter >= n
|
||||
return hexagonalRadius - distanceFromCenter >= n
|
||||
}
|
||||
}
|
|
@ -21,20 +21,20 @@ class GameParameters { // Default values are the default new game
|
|||
var startingEra = TechEra.Ancient
|
||||
|
||||
var isOnlineMultiplayer = false
|
||||
var mods = HashSet<String>()
|
||||
var mods = LinkedHashSet<String>()
|
||||
|
||||
fun clone(): GameParameters {
|
||||
val parameters=GameParameters()
|
||||
parameters.difficulty=difficulty
|
||||
parameters.gameSpeed=gameSpeed
|
||||
parameters.players= ArrayList(players)
|
||||
parameters.numberOfCityStates=numberOfCityStates
|
||||
parameters.noBarbarians=noBarbarians
|
||||
parameters.oneCityChallenge=oneCityChallenge
|
||||
parameters.victoryTypes= ArrayList(victoryTypes)
|
||||
parameters.startingEra=startingEra
|
||||
parameters.isOnlineMultiplayer=isOnlineMultiplayer
|
||||
parameters.mods= HashSet(mods)
|
||||
val parameters = GameParameters()
|
||||
parameters.difficulty = difficulty
|
||||
parameters.gameSpeed = gameSpeed
|
||||
parameters.players = ArrayList(players)
|
||||
parameters.numberOfCityStates = numberOfCityStates
|
||||
parameters.noBarbarians = noBarbarians
|
||||
parameters.oneCityChallenge = oneCityChallenge
|
||||
parameters.victoryTypes = ArrayList(victoryTypes)
|
||||
parameters.startingEra = startingEra
|
||||
parameters.isOnlineMultiplayer = isOnlineMultiplayer
|
||||
parameters.mods = LinkedHashSet(mods)
|
||||
return parameters
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ class Ruleset() {
|
|||
val nations = LinkedHashMap<String, Nation>()
|
||||
val policyBranches = LinkedHashMap<String, PolicyBranch>()
|
||||
val difficulties = LinkedHashMap<String, Difficulty>()
|
||||
val mods = HashSet<String>()
|
||||
val mods = LinkedHashSet<String>()
|
||||
|
||||
fun clone(): Ruleset {
|
||||
val newRuleset = Ruleset()
|
||||
|
@ -146,35 +146,34 @@ class Ruleset() {
|
|||
/** Loading mods is expensive, so let's only do it once and
|
||||
* save all of the loaded rulesets somewhere for later use
|
||||
* */
|
||||
object RulesetCache :HashMap<String,Ruleset>(){
|
||||
fun loadRulesets(){
|
||||
object RulesetCache :HashMap<String,Ruleset>() {
|
||||
fun loadRulesets() {
|
||||
this[""] = Ruleset().apply { load(Gdx.files.internal("jsons")) }
|
||||
|
||||
for(modFolder in Gdx.files.local("mods").list()){
|
||||
for (modFolder in Gdx.files.local("mods").list()) {
|
||||
if (modFolder.name().startsWith('.')) continue
|
||||
try{
|
||||
try {
|
||||
val modRuleset = Ruleset()
|
||||
modRuleset.load(modFolder.child("jsons"))
|
||||
modRuleset.name = modFolder.name()
|
||||
this[modRuleset.name] = modRuleset
|
||||
println ("Mod loaded successfully: " + modRuleset.name)
|
||||
}
|
||||
catch (ex:Exception){
|
||||
println ("Exception loading mod '${modFolder.name()}':")
|
||||
println (" ${ex.localizedMessage}")
|
||||
println (" (Source file ${ex.stackTrace[0].fileName} line ${ex.stackTrace[0].lineNumber})")
|
||||
println("Mod loaded successfully: " + modRuleset.name)
|
||||
} catch (ex: Exception) {
|
||||
println("Exception loading mod '${modFolder.name()}':")
|
||||
println(" ${ex.localizedMessage}")
|
||||
println(" (Source file ${ex.stackTrace[0].fileName} line ${ex.stackTrace[0].lineNumber})")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBaseRuleset() = this[""]!!
|
||||
|
||||
fun getComplexRuleset(mods:Collection<String>): Ruleset {
|
||||
fun getComplexRuleset(mods: Collection<String>): Ruleset {
|
||||
val newRuleset = Ruleset()
|
||||
for(mod in mods)
|
||||
if(containsKey(mod)) {
|
||||
for (mod in mods)
|
||||
if (containsKey(mod)) {
|
||||
newRuleset.add(this[mod]!!)
|
||||
newRuleset.mods+=mod
|
||||
newRuleset.mods += mod
|
||||
}
|
||||
newRuleset.add(getBaseRuleset())
|
||||
return newRuleset
|
||||
|
|
Loading…
Reference in a new issue