Lots off background work for future water tiles
Resized xxxhdpi icon
This commit is contained in:
parent
d7a08cfc01
commit
9c8e173f4e
12 changed files with 178 additions and 71 deletions
BIN
android/ImagesToNotAddToGame/uncivicon2.png
Normal file
BIN
android/ImagesToNotAddToGame/uncivicon2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 366 KiB |
|
@ -1,15 +1,29 @@
|
|||
[
|
||||
// Base terrains
|
||||
{
|
||||
name:"Ocean",
|
||||
type:"Water",
|
||||
food:2,
|
||||
movementCost:1,
|
||||
RGB: [100,100,255]
|
||||
},
|
||||
{
|
||||
name:"Coast",
|
||||
type:"Water",
|
||||
food:2,
|
||||
movementCost:1,
|
||||
RGB: [150,150,255]
|
||||
},
|
||||
{
|
||||
name:"Grassland",
|
||||
type:"BaseTerrain",
|
||||
type:"Land",
|
||||
food:2,
|
||||
movementCost:1,
|
||||
RGB: [109,139,53]
|
||||
},
|
||||
{
|
||||
name:"Plains",
|
||||
type:"BaseTerrain",
|
||||
type:"Land",
|
||||
food:1,
|
||||
production:1,
|
||||
movementCost:1,
|
||||
|
@ -17,27 +31,28 @@
|
|||
},
|
||||
{
|
||||
name:"Tundra",
|
||||
type:"BaseTerrain",
|
||||
type:"Land",
|
||||
food:1,
|
||||
movementCost:1,
|
||||
RGB: [125,122,113]
|
||||
},
|
||||
{
|
||||
name:"Desert",
|
||||
type:"BaseTerrain",
|
||||
type:"Land",
|
||||
movementCost:1,
|
||||
RGB: [ 255, 255, 102]
|
||||
},
|
||||
{
|
||||
name:"Lakes",
|
||||
type:"BaseTerrain",
|
||||
type:"Water",
|
||||
food:1,
|
||||
gold:1
|
||||
gold:1,
|
||||
RGB: [ 200, 200, 255],
|
||||
canHaveOverlay:false
|
||||
},
|
||||
{
|
||||
name:"Hill",
|
||||
type:"BaseTerrain",
|
||||
type:"Land",
|
||||
production:2,
|
||||
movementCost:2,
|
||||
defenceBonus: 0.25,
|
||||
|
|
|
@ -21,8 +21,8 @@ android {
|
|||
applicationId "com.unciv.game"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 26
|
||||
versionCode 135
|
||||
versionName "2.8.3"
|
||||
versionCode 137
|
||||
versionName "2.8.5"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 366 KiB After Width: | Height: | Size: 13 KiB |
|
@ -281,7 +281,7 @@ class UnitAutomation{
|
|||
|
||||
// find best city location within 5 tiles
|
||||
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||
.flatMap { it.getCenterTile().getTilesInDistance(2) }
|
||||
.flatMap { it.getCenterTile().getTilesInDistance(3) }
|
||||
|
||||
// This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once.
|
||||
val nearbyTileRankings = unit.getTile().getTilesInDistance(7)
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2
|
|||
import com.unciv.logic.automation.WorkerAutomation
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.tile.TerrainType
|
||||
import com.unciv.models.gamebasics.unit.BaseUnit
|
||||
import com.unciv.models.gamebasics.unit.UnitType
|
||||
import java.text.DecimalFormat
|
||||
|
@ -89,6 +90,8 @@ class MapUnit {
|
|||
*/
|
||||
fun canMoveTo(tile: TileInfo): Boolean {
|
||||
val tileOwner = tile.getOwner()
|
||||
if(tile.getBaseTerrain().type==TerrainType.Water && baseUnit.unitType.isLandUnit())
|
||||
return false
|
||||
if(tileOwner!=null && tileOwner.civName!=owner
|
||||
&& (tile.isCityCenter() || !civInfo.canEnterTiles(tileOwner))) return false
|
||||
|
||||
|
|
|
@ -8,68 +8,75 @@ import com.unciv.models.gamebasics.tile.TerrainType
|
|||
import com.unciv.models.gamebasics.tile.TileResource
|
||||
import com.unciv.ui.utils.getRandom
|
||||
|
||||
class AlexanderRandomMapGenerator:RandomMapGenerator(){
|
||||
fun generateMap(distance: Int, landExpansionChange:Float){
|
||||
val map = HashMap<Vector2, TileInfo?>()
|
||||
|
||||
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||
map[vector] = null
|
||||
|
||||
val sparkList = ArrayList<Vector2>()
|
||||
val grassland = "Grassland"
|
||||
val ocean = "Ocean"
|
||||
for(i in 0..distance*distance/6){
|
||||
val location = map.filter { it.value==null }.map { it.key }.getRandom()
|
||||
map[location] = TileInfo().apply { baseTerrain= grassland}
|
||||
sparkList.add(location)
|
||||
}
|
||||
|
||||
while(sparkList.any()){
|
||||
val currentSpark = sparkList.getRandom()
|
||||
val emptyTilesAroundSpark = HexMath().GetAdjacentVectors(currentSpark)
|
||||
.filter { map.containsKey(it) && map[it]==null }
|
||||
if(map[currentSpark]!!.baseTerrain==grassland){
|
||||
for(tile in emptyTilesAroundSpark){
|
||||
if(Math.random()<landExpansionChange) map[tile]=TileInfo().apply { baseTerrain=grassland }
|
||||
else map[tile]=TileInfo().apply { baseTerrain=ocean }
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(tile in emptyTilesAroundSpark)
|
||||
map[tile]=TileInfo().apply { baseTerrain=ocean }
|
||||
}
|
||||
sparkList.remove(currentSpark)
|
||||
sparkList.addAll(emptyTilesAroundSpark)
|
||||
}
|
||||
|
||||
// now that we've divided them into land and not-land, stage 2 - seeding areas the way we did with the seed generator!
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Area(var terrain: String) {
|
||||
val locations = ArrayList<Vector2>()
|
||||
fun addTile(position: Vector2) : TileInfo{
|
||||
locations+=position
|
||||
|
||||
val tile = TileInfo()
|
||||
tile.position = position
|
||||
tile.baseTerrain = terrain
|
||||
RandomMapGenerator().addRandomTerrainFeature(tile)
|
||||
RandomMapGenerator().addRandomResourceToTile(tile)
|
||||
return tile
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This generator works by creating a number of seeds of different terrain types in random places,
|
||||
* and choosing a random one each time to expand in a random direction, until the map is filled.
|
||||
* With water, this creates canal-like structures.
|
||||
*/
|
||||
class SeedRandomMapGenerator : RandomMapGenerator() {
|
||||
|
||||
override fun generateMap(distance: Int): HashMap<String, TileInfo> {
|
||||
fun generateMap(distance: Int, waterPercent:Float): HashMap<String, TileInfo> {
|
||||
|
||||
val map = HashMap<Vector2, TileInfo?>()
|
||||
|
||||
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||
map[vector] = null
|
||||
|
||||
class Area(val terrain: String) {
|
||||
val locations = ArrayList<Vector2>()
|
||||
fun addTile(position: Vector2) : TileInfo{
|
||||
locations+=position
|
||||
|
||||
val tile = TileInfo()
|
||||
tile.position = position
|
||||
tile.baseTerrain = terrain
|
||||
addRandomOverlay(tile)
|
||||
addRandomResourceToTile(tile)
|
||||
return tile
|
||||
}
|
||||
}
|
||||
|
||||
val areas = ArrayList<Area>()
|
||||
|
||||
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.BaseTerrain && it.name != "Lakes" }
|
||||
|
||||
|
||||
for (i in 0..(distance*distance/2)){
|
||||
val area = Area(terrains.getRandom().name)
|
||||
val location = map.filter { it.value==null }.map { it.key }.getRandom()
|
||||
map[location] = area.addTile(location)
|
||||
areas += area
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun expandAreas(){
|
||||
val expandableAreas = ArrayList<Area>(areas)
|
||||
while (expandableAreas.isNotEmpty()){
|
||||
val areaToExpand = expandableAreas.getRandom()
|
||||
val availableExpansionVectors = areaToExpand.locations.flatMap { HexMath().GetAdjacentVectors(it) }.distinct()
|
||||
.filter { map.containsKey(it) && map[it] == null }
|
||||
if(availableExpansionVectors.isEmpty()) expandableAreas -= areaToExpand
|
||||
else {
|
||||
val expansionVector = availableExpansionVectors.getRandom()
|
||||
map[expansionVector] = areaToExpand.addTile(expansionVector)
|
||||
}
|
||||
}
|
||||
}
|
||||
expandAreas()
|
||||
|
||||
// After we've assigned all the tiles, there will be some areas that contain only 1 or 2 tiles.
|
||||
// So, we kill those areas, and have the world expand on and cover them too.
|
||||
for(area in areas.toList()){
|
||||
if(area.locations.size<3){
|
||||
areas -= area
|
||||
for(location in area.locations) map[location] = null
|
||||
}
|
||||
}
|
||||
|
||||
expandAreas()
|
||||
divideIntoAreas(6, waterPercent, map)
|
||||
|
||||
val mapToReturn = HashMap<String,TileInfo>()
|
||||
for (entry in map){
|
||||
|
@ -78,8 +85,83 @@ class SeedRandomMapGenerator : RandomMapGenerator() {
|
|||
|
||||
return mapToReturn
|
||||
}
|
||||
|
||||
private fun divideIntoAreas(averageTilesPerArea: Int, waterPercent: Float, map: HashMap<Vector2, TileInfo?>) {
|
||||
val areas = ArrayList<Area>()
|
||||
|
||||
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.Land && it.name != "Lakes" }
|
||||
|
||||
for (i in 0..(map.count { it.value==null } / averageTilesPerArea)) {
|
||||
val terrain = if (Math.random() > waterPercent) terrains.getRandom().name
|
||||
else "Ocean"
|
||||
val area = Area(terrain)
|
||||
val location = map.filter { it.value == null }.map { it.key }.getRandom()
|
||||
map[location] = area.addTile(location)
|
||||
areas += area
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun expandAreas() {
|
||||
val expandableAreas = ArrayList<Area>(areas)
|
||||
while (expandableAreas.isNotEmpty()) {
|
||||
val areaToExpand = expandableAreas.getRandom()
|
||||
val availableExpansionVectors = areaToExpand.locations
|
||||
.flatMap { HexMath().GetAdjacentVectors(it) }.distinct()
|
||||
.filter { map.containsKey(it) && map[it] == null }
|
||||
if (availableExpansionVectors.isEmpty()) expandableAreas -= areaToExpand
|
||||
else {
|
||||
val expansionVector = availableExpansionVectors.getRandom()
|
||||
map[expansionVector] = areaToExpand.addTile(expansionVector)
|
||||
|
||||
val neighbors = HexMath().GetAdjacentVectors(expansionVector)
|
||||
val areasToJoin = areas.filter {
|
||||
it.terrain == areaToExpand.terrain
|
||||
&& it != areaToExpand
|
||||
&& it.locations.any { location -> location in neighbors }
|
||||
}
|
||||
for (area in areasToJoin) {
|
||||
areaToExpand.locations += area.locations
|
||||
areas.remove(area)
|
||||
expandableAreas.remove(area)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expandAreas()
|
||||
|
||||
// After we've assigned all the tiles, there will be some areas that contain only 1 or 2 tiles.
|
||||
// So, we kill those areas, and have the world expand on and cover them too
|
||||
for (area in areas.toList()) {
|
||||
if (area.locations.size < 3) {
|
||||
areas -= area
|
||||
for (location in area.locations) map[location] = null
|
||||
}
|
||||
}
|
||||
|
||||
expandAreas()
|
||||
|
||||
// Once our map has all its tiles, we'll want to change the water tiles to Coasts, Oceans and Lakes
|
||||
|
||||
for (area in areas.filter { it.terrain == "Ocean" && it.locations.size <= 10 }) {
|
||||
// areas with 10 or less tiles are lakes.
|
||||
for (location in area.locations)
|
||||
map[location]!!.baseTerrain = "Lakes"
|
||||
}
|
||||
for (tile in map.values.filter { it != null && it.baseTerrain == "Ocean" }) {
|
||||
if (HexMath().GetAdjacentVectors(tile!!.position)
|
||||
.any { map.containsKey(it) && map[it]!!.getBaseTerrain().type == TerrainType.Land })
|
||||
tile.baseTerrain = "Coast"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This contains the basic randomizing tasks (add random terrain feature/resource)
|
||||
* and a basic map generator where every single tile is individually randomized.
|
||||
* DDoeesn't look very good TBH.
|
||||
*/
|
||||
open class RandomMapGenerator {
|
||||
|
||||
private fun addRandomTile(position: Vector2): TileInfo {
|
||||
|
@ -87,16 +169,16 @@ open class RandomMapGenerator {
|
|||
tileInfo.position = position
|
||||
val terrains = GameBasics.Terrains.values
|
||||
|
||||
val baseTerrain = terrains.filter { it.type === TerrainType.BaseTerrain && it.name != "Lakes" }.getRandom()
|
||||
val baseTerrain = terrains.filter { it.type === TerrainType.Land && it.name != "Lakes" }.getRandom()
|
||||
tileInfo.baseTerrain = baseTerrain.name
|
||||
|
||||
addRandomOverlay(tileInfo)
|
||||
addRandomTerrainFeature(tileInfo)
|
||||
addRandomResourceToTile(tileInfo)
|
||||
|
||||
return tileInfo
|
||||
}
|
||||
|
||||
protected fun addRandomOverlay(tileInfo: TileInfo) {
|
||||
fun addRandomTerrainFeature(tileInfo: TileInfo) {
|
||||
if (tileInfo.getBaseTerrain().canHaveOverlay && Math.random() > 0.7f) {
|
||||
val secondaryTerrains = GameBasics.Terrains.values
|
||||
.filter { it.type === TerrainType.TerrainFeature && it.occursOn!!.contains(tileInfo.baseTerrain) }
|
||||
|
@ -127,7 +209,6 @@ open class RandomMapGenerator {
|
|||
else return filtered.getRandom()
|
||||
}
|
||||
|
||||
|
||||
open fun generateMap(distance: Int): HashMap<String, TileInfo> {
|
||||
val map = HashMap<String, TileInfo>()
|
||||
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||
|
|
|
@ -31,7 +31,7 @@ class TileMap {
|
|||
|
||||
|
||||
constructor(distance: Int) {
|
||||
tileList.addAll(SeedRandomMapGenerator().generateMap(distance).values)
|
||||
tileList.addAll(SeedRandomMapGenerator().generateMap(distance,0f).values)
|
||||
setTransients()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.unciv.logic.map
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.models.gamebasics.tile.TerrainType
|
||||
|
||||
class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
val tileMap = unit.getTile().tileMap
|
||||
|
@ -37,9 +38,10 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||
var totalDistanceToTile:Float
|
||||
val neighborOwner = neighbor.getOwner()
|
||||
val isOwnedByEnemy = neighborOwner!=null && neighborOwner!=unit.civInfo
|
||||
if ((isOwnedByEnemy && neighbor.isCityCenter())// Enemy city,
|
||||
if ( (unit.baseUnit.unitType.isLandUnit() && neighbor.getBaseTerrain().type== TerrainType.Water)
|
||||
|| (isOwnedByEnemy && neighbor.isCityCenter())// Enemy city,
|
||||
|| (neighbor.getUnits().isNotEmpty() && neighbor.getUnits().first().civInfo!=unit.civInfo) // Enemy unit
|
||||
|| (isOwnedByEnemy && !unit.civInfo.canEnterTiles(neighborOwner!!)) // enemyTile
|
||||
|| (isOwnedByEnemy && !unit.civInfo.canEnterTiles(neighborOwner!!)) // enemyTile
|
||||
)
|
||||
totalDistanceToTile = unitMovement // Can't go here.
|
||||
// The reason that we don't just "return" is so that when calculating how to reach an enemy,
|
||||
|
|
|
@ -51,6 +51,7 @@ class Terrain : NamedStats(), ICivilopedia {
|
|||
var RGB: List<Int>? = null
|
||||
var movementCost = 1
|
||||
var defenceBonus:Float = 0f
|
||||
var impassible = false
|
||||
|
||||
fun getColor(): Color = colorFromRGB(RGB!![0], RGB!![1], RGB!![2])
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.unciv.models.gamebasics.tile
|
||||
|
||||
enum class TerrainType {
|
||||
BaseTerrain,
|
||||
Land,
|
||||
Water,
|
||||
TerrainFeature
|
||||
}
|
||||
|
|
|
@ -15,4 +15,8 @@ enum class UnitType{
|
|||
fun isRanged(): Boolean {
|
||||
return this in listOf(Ranged, Siege)
|
||||
}
|
||||
|
||||
fun isLandUnit(): Boolean {
|
||||
return this in listOf(Civilian, Melee, Mounted, Scout, Ranged, Siege)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue