mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-10 07:48:31 +07:00
@ -70,7 +70,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
|
|||||||
* [Pallet](https://thenounproject.com/search/?q=Pallet&i=6862) By James Keuning for Great Artist
|
* [Pallet](https://thenounproject.com/search/?q=Pallet&i=6862) By James Keuning for Great Artist
|
||||||
* [Gear](https://thenounproject.com/search/?q=Gear&i=17369) By Melvin Salas for Great Engineer
|
* [Gear](https://thenounproject.com/search/?q=Gear&i=17369) By Melvin Salas for Great Engineer
|
||||||
* [Beaker](https://thenounproject.com/search/?q=Beaker&i=621510) By Delwar Hossain for Great Scientist
|
* [Beaker](https://thenounproject.com/search/?q=Beaker&i=621510) By Delwar Hossain for Great Scientist
|
||||||
|
* [General](https://thenounproject.com/search/?q=general&i=933566) By anbileru adaleru for Great General
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
@ -413,4 +413,4 @@ Sounds are from FreeSound.org and are either Creative Commons or Public Domain
|
|||||||
* [klick_anlauf](https://freesound.org/people/jascha/sounds/16576/) By jascha as 'metalhit' for metal melee sounds
|
* [klick_anlauf](https://freesound.org/people/jascha/sounds/16576/) By jascha as 'metalhit' for metal melee sounds
|
||||||
* [Horse Neigh 2](https://freesound.org/people/GoodListener/sounds/322450/) By GoodListener as 'horse' for cavalry attack sounds
|
* [Horse Neigh 2](https://freesound.org/people/GoodListener/sounds/322450/) By GoodListener as 'horse' for cavalry attack sounds
|
||||||
* [machine gun 001 - loop](https://freesound.org/people/pgi/sounds/212602/) By pgi as 'machinegun' for machine gun attack sound
|
* [machine gun 001 - loop](https://freesound.org/people/pgi/sounds/212602/) By pgi as 'machinegun' for machine gun attack sound
|
||||||
* [uzzi_full_single](https://freesound.org/people/Deganoth/sounds/348685/) By Deganoth as 'shot' for bullet attacks
|
* [uzzi_full_single](https://freesound.org/people/Deganoth/sounds/348685/) By Deganoth as 'shot' for bullet attacks
|
||||||
|
BIN
android/Images/UnitIcons/Great General.png
Normal file
BIN
android/Images/UnitIcons/Great General.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 830 KiB After Width: | Height: | Size: 833 KiB |
@ -575,5 +575,12 @@
|
|||||||
uniques:["Can speed up construction of a wonder","Can build improvement: Manufactory"]
|
uniques:["Can speed up construction of a wonder","Can build improvement: Manufactory"]
|
||||||
movement:2
|
movement:2
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name:"Great General",
|
||||||
|
unbuildable:true,
|
||||||
|
unitType:"Civilian",
|
||||||
|
uniques:["Can start an 8-turn golden age","Bonus for land units in 2 radius 15%"] //to do : should be able to build mega-fort
|
||||||
|
movement:2
|
||||||
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -93,6 +93,7 @@ class NextTurnAutomation{
|
|||||||
val rangedUnits = mutableListOf<MapUnit>()
|
val rangedUnits = mutableListOf<MapUnit>()
|
||||||
val meleeUnits = mutableListOf<MapUnit>()
|
val meleeUnits = mutableListOf<MapUnit>()
|
||||||
val civilianUnits = mutableListOf<MapUnit>()
|
val civilianUnits = mutableListOf<MapUnit>()
|
||||||
|
val generals = mutableListOf<MapUnit>()
|
||||||
|
|
||||||
for (unit in civInfo.getCivUnits()) {
|
for (unit in civInfo.getCivUnits()) {
|
||||||
if (unit.promotions.canBePromoted()) {
|
if (unit.promotions.canBePromoted()) {
|
||||||
@ -101,10 +102,10 @@ class NextTurnAutomation{
|
|||||||
unit.promotions.addPromotion(availablePromotions.getRandom().name)
|
unit.promotions.addPromotion(availablePromotions.getRandom().name)
|
||||||
}
|
}
|
||||||
|
|
||||||
val unitType = unit.type
|
|
||||||
when {
|
when {
|
||||||
unitType.isRanged() -> rangedUnits.add(unit)
|
unit.type.isRanged() -> rangedUnits.add(unit)
|
||||||
unitType.isMelee() -> meleeUnits.add(unit)
|
unit.type.isMelee() -> meleeUnits.add(unit)
|
||||||
|
unit.name == "Great General" -> generals.add(unit) //generals move after military units
|
||||||
else -> civilianUnits.add(unit)
|
else -> civilianUnits.add(unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +113,7 @@ class NextTurnAutomation{
|
|||||||
for (unit in civilianUnits) UnitAutomation().automateUnitMoves(unit) // They move first so that combat units can accompany a settler
|
for (unit in civilianUnits) UnitAutomation().automateUnitMoves(unit) // They move first so that combat units can accompany a settler
|
||||||
for (unit in rangedUnits) UnitAutomation().automateUnitMoves(unit)
|
for (unit in rangedUnits) UnitAutomation().automateUnitMoves(unit)
|
||||||
for (unit in meleeUnits) UnitAutomation().automateUnitMoves(unit)
|
for (unit in meleeUnits) UnitAutomation().automateUnitMoves(unit)
|
||||||
|
for (unit in generals) UnitAutomation().automateUnitMoves(unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reassignWorkedTiles(civInfo: CivilizationInfo) {
|
private fun reassignWorkedTiles(civInfo: CivilizationInfo) {
|
||||||
|
@ -33,6 +33,8 @@ class UnitAutomation{
|
|||||||
return SpecificUnitAutomation().automateWorkBoats(unit)
|
return SpecificUnitAutomation().automateWorkBoats(unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unit.name == "Great General")
|
||||||
|
return SpecificUnitAutomation().automateGeneral(unit)
|
||||||
if(unit.name.startsWith("Great")
|
if(unit.name.startsWith("Great")
|
||||||
&& unit.name in GreatPersonManager().statToGreatPersonMapping.values){ // So "Great War Infantry" isn't caught here
|
&& unit.name in GreatPersonManager().statToGreatPersonMapping.values){ // So "Great War Infantry" isn't caught here
|
||||||
return SpecificUnitAutomation().automateGreatPerson(unit)// I don't know what to do with you yet.
|
return SpecificUnitAutomation().automateGreatPerson(unit)// I don't know what to do with you yet.
|
||||||
@ -397,6 +399,29 @@ class SpecificUnitAutomation{
|
|||||||
else UnitAutomation().explore(unit, unit.getDistanceToTiles())
|
else UnitAutomation().explore(unit, unit.getDistanceToTiles())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun automateGeneral(unit: MapUnit){
|
||||||
|
//try to follow nearby units. Do not garrison in city if possible
|
||||||
|
val militantToCompany = unit.getDistanceToTiles().map { it.key }
|
||||||
|
.firstOrNull {val militant = it.militaryUnit;
|
||||||
|
militant != null && militant.civInfo == unit.civInfo
|
||||||
|
&& (it.civilianUnit == null || it.civilianUnit == unit)
|
||||||
|
&& militant.getMaxMovement() <= 2.0f && !it.isCityCenter()}
|
||||||
|
|
||||||
|
if(militantToCompany!=null) {
|
||||||
|
unit.movementAlgs().headTowards(militantToCompany)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//if no unit to follow, take refuge in city.
|
||||||
|
val cityToGarison = unit.civInfo.cities.map {it.getCenterTile()}
|
||||||
|
.filter {it.civilianUnit == null && unit.canMoveTo(it) && unit.movementAlgs().canReach(it)}
|
||||||
|
.minBy { it.arialDistanceTo(unit.currentTile) }
|
||||||
|
if (cityToGarison != null) {
|
||||||
|
unit.movementAlgs().headTowards(cityToGarison)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fun rankTileAsCityCenter(tileInfo: TileInfo, nearbyTileRankings: Map<TileInfo, Float>): Float {
|
fun rankTileAsCityCenter(tileInfo: TileInfo, nearbyTileRankings: Map<TileInfo, Float>): Float {
|
||||||
val bestTilesFromOuterLayer = tileInfo.getTilesAtDistance(2)
|
val bestTilesFromOuterLayer = tileInfo.getTilesAtDistance(2)
|
||||||
|
@ -96,6 +96,7 @@ class Battle(val gameInfo:GameInfo) {
|
|||||||
var amountToAdd = amount
|
var amountToAdd = amount
|
||||||
if(thisCombatant.getCivilization().policies.isAdopted("Military Tradition")) amountToAdd = (amountToAdd * 1.5f).toInt()
|
if(thisCombatant.getCivilization().policies.isAdopted("Military Tradition")) amountToAdd = (amountToAdd * 1.5f).toInt()
|
||||||
thisCombatant.unit.promotions.XP += amountToAdd
|
thisCombatant.unit.promotions.XP += amountToAdd
|
||||||
|
thisCombatant.getCivilization().greatPeople.greatGeneralPoints += amountToAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attacker.isMelee()){
|
if(attacker.isMelee()){
|
||||||
|
@ -61,6 +61,16 @@ class BattleDamage{
|
|||||||
if(requiredResource!=null && combatant.getCivilization().getCivResourcesByName()[requiredResource]!!<0){
|
if(requiredResource!=null && combatant.getCivilization().getCivResourcesByName()[requiredResource]!!<0){
|
||||||
modifiers["Missing resource"]=-0.25f
|
modifiers["Missing resource"]=-0.25f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//to do : performance improvement
|
||||||
|
if (combatant.getUnitType().isLandUnit()) {
|
||||||
|
val nearbyCivUnits = combatant.unit.getTile().getTilesInDistance(2)
|
||||||
|
.filter {it.civilianUnit?.civInfo == combatant.unit.civInfo}
|
||||||
|
.map {it.civilianUnit}
|
||||||
|
if (nearbyCivUnits.any { it!!.hasUnique("Bonus for land units in 2 radius 15%") }) {
|
||||||
|
modifiers["Great general"]=0.15f
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (combatant.getCivilization().policies.isAdopted("Honor") && enemy.getCivilization().isBarbarianCivilization())
|
if (combatant.getCivilization().policies.isAdopted("Honor") && enemy.getCivilization().isBarbarianCivilization())
|
||||||
|
@ -350,11 +350,15 @@ class CivilizationInfo {
|
|||||||
city.endTurn()
|
city.endTurn()
|
||||||
}
|
}
|
||||||
|
|
||||||
val greatPerson = greatPeople.getNewGreatPerson()
|
//if no city available, addGreatPerson will throw exception
|
||||||
if (greatPerson != null) {
|
if (cities.isNotEmpty()) {
|
||||||
addGreatPerson(greatPerson)
|
val greatPerson = greatPeople.getNewGreatPerson()
|
||||||
|
if (greatPerson != null) {
|
||||||
|
addGreatPerson(greatPerson)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
goldenAges.endTurn(happiness)
|
goldenAges.endTurn(happiness)
|
||||||
getCivUnits().forEach { it.endTurn() }
|
getCivUnits().forEach { it.endTurn() }
|
||||||
diplomacy.values.forEach{it.nextTurn()}
|
diplomacy.values.forEach{it.nextTurn()}
|
||||||
|
@ -5,7 +5,9 @@ import com.unciv.models.stats.Stats
|
|||||||
|
|
||||||
class GreatPersonManager {
|
class GreatPersonManager {
|
||||||
var pointsForNextGreatPerson = 100
|
var pointsForNextGreatPerson = 100
|
||||||
|
var pointsForNextGreatGeneral = 30
|
||||||
var greatPersonPoints = Stats()
|
var greatPersonPoints = Stats()
|
||||||
|
var greatGeneralPoints = 0
|
||||||
var freeGreatPeople=0
|
var freeGreatPeople=0
|
||||||
|
|
||||||
val statToGreatPersonMapping = HashMap<Stat,String>().apply {
|
val statToGreatPersonMapping = HashMap<Stat,String>().apply {
|
||||||
@ -20,11 +22,20 @@ class GreatPersonManager {
|
|||||||
toReturn.freeGreatPeople=freeGreatPeople
|
toReturn.freeGreatPeople=freeGreatPeople
|
||||||
toReturn.greatPersonPoints=greatPersonPoints.clone()
|
toReturn.greatPersonPoints=greatPersonPoints.clone()
|
||||||
toReturn.pointsForNextGreatPerson=pointsForNextGreatPerson
|
toReturn.pointsForNextGreatPerson=pointsForNextGreatPerson
|
||||||
|
toReturn.pointsForNextGreatGeneral = pointsForNextGreatGeneral
|
||||||
|
toReturn.greatGeneralPoints = greatGeneralPoints
|
||||||
return toReturn
|
return toReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewGreatPerson(): String? {
|
fun getNewGreatPerson(): String? {
|
||||||
val greatPerson: String? = null
|
val greatPerson: String? = null
|
||||||
|
|
||||||
|
if (greatGeneralPoints > pointsForNextGreatGeneral) {
|
||||||
|
greatGeneralPoints -= pointsForNextGreatGeneral
|
||||||
|
pointsForNextGreatGeneral += 50
|
||||||
|
return "Great General"
|
||||||
|
}
|
||||||
|
|
||||||
val greatPersonPointsHashmap = greatPersonPoints.toHashMap()
|
val greatPersonPointsHashmap = greatPersonPoints.toHashMap()
|
||||||
for(entry in statToGreatPersonMapping){
|
for(entry in statToGreatPersonMapping){
|
||||||
if(greatPersonPointsHashmap[entry.key]!!>pointsForNextGreatPerson){
|
if(greatPersonPointsHashmap[entry.key]!!>pointsForNextGreatPerson){
|
||||||
|
@ -177,6 +177,10 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
|
|||||||
greatPeopleTable.add(greatPersonPoints[entry.key]!!.toInt().toString()+"/"+pointsToGreatPerson)
|
greatPeopleTable.add(greatPersonPoints[entry.key]!!.toInt().toString()+"/"+pointsToGreatPerson)
|
||||||
greatPeopleTable.add(greatPersonPointsPerTurn[entry.key]!!.toInt().toString()).row()
|
greatPeopleTable.add(greatPersonPointsPerTurn[entry.key]!!.toInt().toString()).row()
|
||||||
}
|
}
|
||||||
|
val pointsForGreatGeneral = playerCivInfo.greatPeople.greatGeneralPoints.toInt().toString()
|
||||||
|
val pointsForNextGreatGeneral = playerCivInfo.greatPeople.pointsForNextGreatGeneral.toInt().toString()
|
||||||
|
greatPeopleTable.add("Great General".tr())
|
||||||
|
greatPeopleTable.add(pointsForGreatGeneral+"/"+pointsForNextGreatGeneral).row()
|
||||||
greatPeopleTable.pack()
|
greatPeopleTable.pack()
|
||||||
return greatPeopleTable
|
return greatPeopleTable
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class GreatPersonPickerScreen : PickerScreen() {
|
|||||||
closeButton.isVisible=false
|
closeButton.isVisible=false
|
||||||
rightSideButton.setText("Choose a free great person")
|
rightSideButton.setText("Choose a free great person")
|
||||||
for (unit in GameBasics.Units.values
|
for (unit in GameBasics.Units.values
|
||||||
.filter { it.name in GreatPersonManager().statToGreatPersonMapping.values})
|
.filter { it.name in GreatPersonManager().statToGreatPersonMapping.values || it.name == "Great General"})
|
||||||
{
|
{
|
||||||
val button = Button(skin)
|
val button = Button(skin)
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ class UnitActions {
|
|||||||
}.sound("chimes")
|
}.sound("chimes")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.name == "Great Artist" && !unit.isEmbarked()) {
|
if (unit.hasUnique("Can start an 8-turn golden age") && !unit.isEmbarked()) {
|
||||||
actionList += UnitAction( "Start Golden Age",unit.currentMovement != 0f
|
actionList += UnitAction( "Start Golden Age",unit.currentMovement != 0f
|
||||||
) {
|
) {
|
||||||
unit.civInfo.goldenAges.enterGoldenAge()
|
unit.civInfo.goldenAges.enterGoldenAge()
|
||||||
|
Reference in New Issue
Block a user