Merge branch 'master' into master

This commit is contained in:
divizdev 2019-04-14 21:22:14 +03:00 committed by GitHub
commit 8fe889dc96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 840 additions and 527 deletions

View file

@ -33,6 +33,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Catapult](https://thenounproject.com/search/?q=Spear&i=1233840) By Jakub Ukrop
* [Unloaded Crossbow](https://thenounproject.com/term/unloaded-crossbow/815992/) By Hamish as Ballista
* [Sword](https://thenounproject.com/search/?q=Sword&i=1215443) By Guilherme Furtado for Swordsman
* [Roman Helmet](https://thenounproject.com/search/?q=legion&i=440134) By parkjisun for Legion
* [Horse](https://thenounproject.com/search/?q=Horse&i=1373793) By AFY Studio for Horseman
* [Horse Head](https://thenounproject.com/search/?q=Cavalry&i=374037) By Juan Pablo Bravo for Companion Cavalry
@ -55,6 +56,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Black powder musket](https://thenounproject.com/term/black-powder-musket/1202078/) By Jarem Fyre for Minuteman
* [Rapier](https://thenounproject.com/search/?q=musketeer&i=819822) By Hamish for Musketeer
* [Ship](https://thenounproject.com/term/ship/1293899/) By Orin Zuu for Frigate
* [Ship](https://thenounproject.com/search/?q=ship&i=800131) By Mungang Kim for Ship of the Line
* [Lance](https://thenounproject.com/search/?q=Lance&i=440122) By parkjisun for Lancer
### Industrial
@ -67,6 +69,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
### Modern
* [Helmet](https://thenounproject.com/term/helmet/25216/) By Daniel Turner for Great War Infantry
* [Cap](https://thenounproject.com/search/?q=kepi&i=950267) By Creative Mania for Foreign Legion
* [Tank](https://thenounproject.com/term/tank/1287510/) By corpus delicti for Landship
* [Warship](https://thenounproject.com/term/warship/1597474/) By zidney for Destroyer
* [Battleship](https://thenounproject.com/search/?q=battleship&i=1986807) By Vitaliy Gorbachev, KZ for Battleship
@ -136,6 +139,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Storehouse](https://thenounproject.com/term/storehouse/966786/) By Pedro Santos for Granary
* [Great Wall Of China](https://thenounproject.com/term/great-wall-of-china/146039/) By Arthur Shlain for Walls
* [Markadan Tower](https://thenounproject.com/search/?q=fortification&i=2107694) by Vectors Market for Walls of Babylon
* [Block](https://thenounproject.com/term/block/1711553/) By Monjin Friends for Stone Works
* [korean palace](https://thenounproject.com/term/korean-palace/1797542/) By 1516 for Palace
* [Obelisk](https://thenounproject.com/term/obelisk/749104/) By Eliricon for Monument
@ -153,6 +157,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Anubis](https://thenounproject.com/term/anubis/1080090/) By Carpe Diem for Burial Tomb
* [Parthenon](https://thenounproject.com/term/parthenon/493272/) By Christopher T. Howlett for The Oracle
* [Stadium](https://thenounproject.com/term/stadium/1500595/) By sandra for Colloseum
* [Terracotta Army](https://thenounproject.com/search/?q=terracotta&i=2306346) By Supalerk Laipawat
* [Stadium](https://thenounproject.com/term/stadium/1152530/) By Creaticca Creative Agency for Circus Maximus
* [Market](https://thenounproject.com/term/market/1723050/) By sofi
* [Bazaar](https://thenounproject.com/term/bazaar/902288/) By Tokka Elkholy
@ -187,6 +192,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Forbidden City](https://thenounproject.com/term/forbidden-city/1797540/) By 1516
* [Theatre](https://thenounproject.com/term/theatre/1780401/) By b farias
* [Tower of Pisa](https://thenounproject.com/search/?q=leaning%20tower%20of%20pisa&i=1002578) By Pedro Santos
* [Himeji Castle](https://thenounproject.com/search/?q=himeji&i=1125277) By Chanut is Industries
* [Windmill](https://thenounproject.com/term/windmill/1705107/) By corpus delicti
* [Taj Mahal](https://thenounproject.com/term/taj-mahal/1907755/) By Felipe Alvarado
* [Observatory](https://thenounproject.com/term/observatory/1259/) By Nathan Driskell
@ -211,6 +217,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Statue of Liberty](https://thenounproject.com/search/?q=statue%20of%20liberty&i=1801199) By 1516
* [Christ the redeemer](https://thenounproject.com/term/christ-the-redeemer/56112/) By Stefan Spieler for Cristo Redentor
* [St. Petersburg](https://thenounproject.com/search/?q=kremlin&i=1569704) By Carpe Diem for Kremlin
* [Neuschwanstein](https://thenounproject.com/search/?q=Neuschwanstein&i=2107683) By Vectors Market
### Information Era

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 947 KiB

After

Width:  |  Height:  |  Size: 979 KiB

View file

@ -82,25 +82,23 @@
hurryCostModifier:25,
requiredTech:"Masonry"
},
/*
{
name:"Walls of Babylon",
replaces:"Walls",
cost:65,
uniqueTo:"Babylon",
cityStrength:6,
cityHealth:100,
hurryCostModifier:25,
requiredTech:"Masonry"
//Babylonian unique building that replaces Walls.
},
*/
{
name:"The Pyramids",
culture:1,
greatPersonPoints:{production:1},
isWonder:true,
uniques:["Worker construction increased 25%","Provides 2 free workers"],
requiredTech:"Mathematics"
requiredTech:"Masonry"
},
{
name:"Barracks",
@ -116,7 +114,7 @@
greatPersonPoints:{gold:1},
isWonder:true,
uniques:["Can only be built in coastal cities", "+1 gold from worked water tiles in city"],
requiredTech:"Mathematics"
requiredTech:"Iron Working"
},
{
name:"Krepost",
@ -180,6 +178,12 @@
hurryCostModifier:25,
requiredTech:"Construction"
},
{
name:"Terracotta Army",
culture:6,
isWonder:true,
requiredTech:"Construction"
},
{
name:"Temple",
culture:3,
@ -452,6 +456,15 @@
uniques:["Free Great Person"]
requiredTech:"Printing Press"
},
{
name:"Himeji Castle",
culture:1,
isWonder:true,
greatPersonPoints:{production:2}
providesFreeBuilding:"Castle",
uniques:["+15% combat strength for units fighting in friendly territory"] // todo
requiredTech:"Gunpowder"
},
{
name:"Museum",
culture:5,
@ -615,6 +628,15 @@
uniques:["Defensive buildings in all cities are 25% more effective"],
requiredTech:"Railroad"
},
{
name:"Neuschwanstein",
happiness:2,
culture:4,
gold:6,
isWonder:true,
uniques:["+1 happiness, +2 culture and +3 gold from every Castle"],
requiredTech:"Railroad"
},
// Information Era

View file

@ -303,6 +303,8 @@
mainColor:[ 41,83,42],
secondaryColor:[146,221,9],
uniqueName:"Trade Caravans",
unique:"+1 Gold from each Trade Route, Oil resources provide double quantity"
cities:["Mecca","Medina","Damascus","Baghdad","Najran","Kufah","Basra","Khurasan","Anjar","Fustat",
"Aden","Yamama","Muscat","Mansura","Bukhara","Fez","Shiraz","Merw","Balkh","Mosul",
"Aydab","Bayt","Suhar","Taif","Hama","Tabuk","Sana'a","Shihr","Tripoli","Tunis"]

View file

@ -352,8 +352,8 @@
leaderName:"Oda Nobunaga",
adjective:["giapponese"],
startIntroPart1: "Tu sia benedetto, nobile Oda Nobunaga, signore del Giappone, la terra del Sol Levante! Possa tu camminare a lungo in mezzo ai suoi meravigliosi boccioli di ciliegio. I giapponesi sono un popolo isolano, fiero e pio con una ricca cultura artistica e letteraria. La tua civiltà esiste per migliaia di anni, anni di sanguinose lotte, espansioni ed isolazioni, di grandi ricchezze e povertà. Oltre alla loro prodezza sul campo di battaglia, il tuo popolo è abile anche nell'industria, e le loro innovazioni tecnologiche e le loro grandi fabbriche sono l'invidia degli altri popoli in tutto il globo."
startIntroPart2: "Leggendario damiyo, prenderai le redini del destino? Porterai alla tua famiglia e al tuo popolo l'onore e la gloria che meritano? Alzerai di nuovo la tua spada e marcerai verso il trionfo? Riuscirai a plasmare una civiltà in grado di superare la prova del tempo?"
startIntroPart1: "Salute a te, nobile Oda Nobunaga, sovrano del Giappone, la terra del Sol Levante, dove sorge il Sole! Possa tu a lungo passeggiare in mezzo ai suoi prati in fiore. I giapponesi sono un popolo isolano, fiero e pio, dalla ricca cultura artistica e letteraria. La tua civiltà è millenaria. Sono stati anni di lotte sanguinose, di espansioni ed isolamenti, di grandi ricchezze e povertà. Oltre alla sua prodezza sul campo di battaglia, il tuo popolo può anche vantare una stupefacente operosità. La sua superiorità tecnologiche e le sue grandiose fabbriche sono l'invidia degli altri popoli di tutte le latitudini."
startIntroPart2: "O leggendario damiyo, prenderai in mano le redini del destino? Porterai alla tua famiglia e al tuo popolo l'onore e la gloria che meritano? Alzerai di nuovo la tua spada e marcerai verso il trionfo? Riuscirai a plasmare una civiltà in grado di superare la prova del tempo?"
declaringWar:"Come samurai siamo gente onesta, e noi troviamo onesto volerti esprimere la nostra intenzione di cancellarti dalla faccia della terra con questo messaggio."
attacked:"Fatti pure avanti! Il kamikaze (vento divino) ci proteggerà, e tu cadrai, come altri prima di te!"

View file

@ -29,14 +29,6 @@
Simplified_Chinese:"下一回合"
Portuguese:"Proximo turno"
Japanese:"次のターン"
Polish:"Następna tura"
Indonesian:"Giliran berikutnya"
Philippino:"Susunod na pagliko"
Czech:"Další otočení"
Slovak:"Ďalšie otočenie"
Sloven:"Naslednji zavoj"
Croatian:"Sljedeći red"
Danish:"Næste tur"
}
"Working...":{ // Displayed when next turn is being...turned
@ -194,7 +186,7 @@
Dutch:"Verbetering bouwen"
Spanish:"Construir mejora"
Simplified_Chinese:"建造建筑"
Portuguese:"Construir melhoria"
Portuguese:"Construir melhoria"
Japanese:"構造改善"
}
@ -725,7 +717,7 @@
}
"Worked tiles":{
Italian:"celle sfruttate"
Italian:"Celle sfruttate"
Russian:"обработанные клетки"
French:"cases exploités"
Romanian:"celule lucrate"
@ -2517,7 +2509,7 @@
German:"Dschungel abholzen"
}
"Remove Marsh":{
Italian:"Rimuovi palude"
Italian:"Bonifica palude"
Russian:"Осушить болото"
French:"Assécher le marais"
Romanian:"Asanează mlaștina"
@ -4052,7 +4044,7 @@
// Policy picker screen
"You have entered the [newEra] era!":{
Italian:"Sei entrato in una nuova era, [newEra]!"
Italian:"Sei entrato in una nuova era, l'[newEra]!" //[newEra] not translated in Italian
Russian:"Вы вошли в эпоху [newEra]!"
French:"Vous êtes entré dans l'ère [newEra]!"
Romanian:"Ai intrat în epoca [newEra]!"
@ -4261,6 +4253,10 @@
Russian:"заменяет"
}
"[resourceName] not required":{
Italian:"Risorsa [resourceName] non richiesta"
}
"National ability":{ // the unique ability that each nation has
Italian:"Abilità della civiltà"
Romanian:"Abilitate a națiunii"
@ -5030,7 +5026,7 @@
German:"Name"
}
"Closest city":{
Italian:"La città più vicina"
Italian:"Città più vicina"
Russian:"Ближайший город"
French:"Ville la plus proche"
Romanian:"Cel mai apropiat oraș"
@ -5172,6 +5168,9 @@
Portuguese:"Muralhas"
German:"Mauern"
}
"Walls of Babylon":{
Italian:"Mura di Babilonia"
}
"The Pyramids":{
Italian:"Grandi Piramidi"
@ -5236,8 +5235,12 @@
French:"Cout d'acquisition en or et en culture de nouvelle cases réduit de 25% dans cette ville"
}
"Colossus":{}
"+1 gold from worked water tiles in city":{}
"Colossus":{
Italian:"Colosso"
}
"+1 gold from worked water tiles in city":{
Italian:"+1 Oro per ogni risorsa anfibia sfruttata dalla città."
}
"Temple":{
Italian:"Tempio"
@ -5422,6 +5425,11 @@
Portuguese:"Coliseu"
German:"Collosseum"
}
"Terracotta Army":{
Italian:"Esercito di terracotta"
}
"Market":{
Italian:"Mercato"
Russian:"Рынок"
@ -5560,8 +5568,12 @@
Portuguese:"40% da comida é mantida depois de um novo cidadão nascer"
}
"Great Wall":{}
"Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)":{}
"Great Wall":{
Italian:"Grande Muraglia"
}
"Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)":{
Italian:"Le unità nemiche impiegano un punto Movimento extra se all'interno del tuo territorio (diventa obsoleta con la Dinamite)."
}
"Workshop":{
Italian:"Bottega"
@ -5687,19 +5699,6 @@
Simplified_Chinese:"购买新地块的成本降低了25%"
Portuguese:"Custa de comprar novos terrenos reduzido em 25%"
}
/*
//New Wonder projected: Himeji Castle! Free Castle in City which possessed it, and +15% Strenght for units in friendly territory
//Also, +1 Culture and +2 Great Engineer Points. Requires Gunpowder
"Himeji Castle":{
Italian:"Castello di Himeji"
French:"Château d'Himeji"
}
"+15% Combat Strenght for units fighting in friendly territory":{
Italian:"+15% Forza per le unità che combattono in territorio amico"
French:"+15% force pour toutes les unités dans un territoire allié"
}
*/
"Porcelain Tower":{
Italian:"Torre di Porcellana"
@ -5834,8 +5833,7 @@
Spanish:"La Torre Inclinada De Pizza"
German:"Schiefer Turm von Pisa"
French:"Tour de Pise"
}
}
"Free Great Person":{
Italian:"Ottieni un Grande Personaggio gratuito"
Romanian:"Persoană mare gratuită"
@ -5844,6 +5842,13 @@
French:"Personnage illustre gratuit"
}
"Himeji Castle":{
Italian:"Castello di Himeji"
}
"+15% combat strength for units fighting in friendly territory":{
Italian:"+15% Forza per le unità che combattono in territorio amico"
}
"Taj Mahal":{
Italian:"Taj Mahal" //same in Italian
Russian:"Тадж-Махал"
@ -6036,6 +6041,13 @@
Italian:"+25% efficacia delle strutture difensive in tutte le città"
}
"Neuschwanstein":{
Italian:"Castello di Neuschwanstein"
}
"+1 happiness, +2 culture and +3 gold from every Castle":{
Italian:"+1 Felicitù, +2 Cultura e +3 Oro per ogni Castello"
}
"Military Academy":{
Italian:"Accademia militare"
Russian:"Военная академия"
@ -6470,6 +6482,7 @@
Portuguese:"Espadachin" // may replace with guerreiro com espada if nescessary
German:"Schwertkämpfer"
}
"Legion":{
Italian:"Legionario"
Romanian:"Legionar"
@ -6477,7 +6490,14 @@
Simplified_Chinese:"古罗马军团"
German:"Legionär"
French:"Légion"
} // Rome unique
}
"Can construct roads":{
Italian:"Può costruire Strade"
}
"Construct road":{
Italian:"Costruisci Strada"
} // for unit action button
"Horseman":{
Italian:"Guerriero a cavallo" //wrong translation by Smashfanful
Russian:"Всадник"
@ -6587,6 +6607,14 @@
German:"Kamel-Bogenschütze"
French:"Archer méhariste"
}
"Samurai":{
Italian:"Samurai" //Same as in Italian
}
"Combat very likely to create Great Generals":{
Italian:"Può generare un Grande Generale combattendo"
}
// Renaissance units
"Caravel":{
@ -6701,6 +6729,7 @@
Portuguese:"Cavalaria"
German:"Kavallerie"
}
"Cossack":{
Italian:"Cosacco"
Romanian:"Cazac"
@ -6709,7 +6738,7 @@
Russian:"Казаки"
German:"Kosak"
French:"Cosaque"
} // Russia unique
}
"Artillery":{
Italian:"Artiglieria"
@ -6732,7 +6761,7 @@
German:"Panzerschiff"
}
// Modern units (do these, yes)
// Modern units
"Landship":{
Italian:"Nave di terra"
Romanian:"Vehicul terestru"
@ -6742,6 +6771,7 @@
German:"Landschiff"
French:"Véhicule terrestre" //official translation but ugly
}
"Great War Infantry":{
Italian:"Fante della Grande Guerra"
Romanian:"Infanteria Marelui Război"
@ -6751,6 +6781,19 @@
German:"Weltkriegs Infanterie"
French:"Infanterie de la grande guerre"
}
"Foreign Legion":{
Italian:"Legione Straniera"
}
"+20% bonus outside friendly territory":{
Italian:"+20% Forza fuori da territorio amico"
}
"Foreign Land":{ // for battle table combat percentage
Italian:"Terra Straniera"
}
"Destroyer":{
Italian:"Cacciatorpediniere"
Romanian:"Distrugător"
@ -8202,7 +8245,7 @@
Russian:"Вы одержали победу завоевания!"
}
"One more turn...!":{
Italian:"Solo un altro turno..."
Italian:"Aspetta! Solo un altro turno..."
German:"Nur noch eine Runde..."
French:"Un autre tour... !"
Russian:"Еще один ход...!"
@ -8376,10 +8419,17 @@
German:"Angriff"
French:"Charge"
}
"Bonus vs wounded units 33%":{
Italian:"+33% forza contro unità ferite"
French:"+33% force contre les unités montées"
Russian:"Бонус против раненых 33%"
}
"wounded units":{
Italian:"unità ferite"
French:"unités montées"
}
"Mobility":{
Italian:"Mobilità"
@ -8663,4 +8713,7 @@
Italian:"Editor mappe"
Russian:"Редактор карт"
}
"Language":{
Italian:"Lingua"
}
}

View file

@ -73,8 +73,8 @@
{
name:"Maori Warrior",
unitType:"Melee",
uniqueTo:"Aztec",
replaces:"Polynesia",
uniqueTo:"Polynesia",
replaces:"Warrior",
movement:2,
strength:8,
cost: 40,
@ -85,6 +85,19 @@
attackSound:"nonmetalhit"
//Polynesian unique unit. All Units near him have -10% strenght
},
{
name:"Brute",
unitType:"Melee",
uniqueTo:"Barbarian",
replaces:"Warrior",
movement:2,
strength:8,
cost: 20,
obsoleteTech:"Metal Casting",
upgradesTo:"Swordsman",
attackSound:"nonmetalhit"
//Barbarian unique unit
},
*/
{
name:"Archer",
@ -205,7 +218,6 @@
hurryCostModifier:20,
attackSound:"arrow"
},
/*
{
name:"War Chariot",
unitType:"Ranged",
@ -221,8 +233,8 @@
uniques:["No defensive terrain bonus","Rough terrain penalty"],
hurryCostModifier:20,
attackSound:"arrow"
//This is the Egyptian unique unit. It replaces Chariot Archer, moves faster and needs no horses.
},
/*
{
name:"War Elephant",
unitType:"Ranged",
@ -333,7 +345,6 @@
hurryCostModifier:20,
attackSound:"metalhit"
},
/*
{
name:"Legion",
unitType:"Melee",
@ -346,10 +357,11 @@
upgradesTo:"Longswordsman",
obsoleteTech:"Steel",
requiredResource:"Iron",
uniques:["Can construct roads"]
hurryCostModifier:20,
attackSound:"metalhit"
//Roman unique unit. It is stronger than Swordsman. It should also build roads (maybe railroads, too). It takes more to Steel to make it obsolete.
},
/*
{
name:"Mohawk Warrior",
unitType:"Melee",
@ -431,9 +443,8 @@
hurryCostModifier:20,
attackSound:"arrow"
},
/*
{
name:"Chu-ko-nu",
name:"Chu-Ko-Nu",
unitType:"Ranged",
uniqueTo:"China",
movement:2,
@ -444,11 +455,10 @@
requiredTech:"Machinery",
upgradesTo:"Gatling Gun",
obsoleteTech:"Industrialization",
promotions:["Logistics"],
hurryCostModifier:20,
attackSound:"arrow"
//Chinese unique unit. It is weaker than Crossbowman but can attack twice.
},
*/
{
name:"Longbowman",
unitType:"Ranged",
@ -763,7 +773,6 @@
upgradesTo:"Battleship",
hurryCostModifier:20
},
/*
{
name:"Ship of the Line",
unitType:"WaterRanged",
@ -774,13 +783,12 @@
rangedStrength:35,
cost: 185,
requiredResource:"Iron",
uniques:["Extra sight 1"]
uniques:["+1 Visibility Range"]
requiredTech:"Navigation",
obsoleteTech:"Electronics",
upgradesTo:"Battleship",
hurryCostModifier:20
},
*/
{
name:"Lancer",
unitType:"Mounted",
@ -873,7 +881,6 @@
hurryCostModifier:20,
attackSound:"horse"
},
/*
{
name:"Cossack",
unitType:"Mounted",
@ -885,11 +892,11 @@
requiredTech:"Military Science",
requiredResource:"Horses",
upgradesTo:"Landship",
uniques:["Can move after attacking","No defensive terrain bonus","Penalty vs City 33%","Damaged Enemy Bonus 33%" ],
uniques:["Can move after attacking","No defensive terrain bonus","Penalty vs City 33%","Bonus vs wounded units 33%" ],
hurryCostModifier:20,
attackSound:"horse"
//This Russian unique unit should replace Cavalry and also deal +33% damage to damaged units.
},
/*
{
name:"Comanche Rider",
unitType:"Mounted",
@ -996,6 +1003,21 @@
obsoleteTech:"Plastics"
attackSound:"shot"
},
{
name:"Foreign Legion",
unitType:"Melee",
replaces:"Great War Infantry",
uniqueTo:"France",
movement:2,
strength:50,
cost: 320,
requiredTech:"Replaceable Parts",
hurryCostModifier:20,
upgradesTo:"Infantry",
obsoleteTech:"Plastics",
uniques:["+20% bonus outside friendly territory"],
attackSound:"shot"
},
{
name:"Infantry",
unitType:"Melee",

View file

@ -21,8 +21,8 @@ android {
applicationId "com.unciv.app"
minSdkVersion 14
targetSdkVersion 28
versionCode 224
versionName "2.14.4"
versionCode 227
versionName "2.14.7"
}
// Had to add this crap for Travis to build, it wanted to sign the app

View file

@ -20,6 +20,7 @@ class GameParameters{
var humanNations=ArrayList<String>().apply { add("Babylon") }
var numberOfEnemies=3
var mapType= MapType.Perlin
var noBarbarians=false
var mapFileName :String?=null
}

View file

@ -47,7 +47,7 @@ class GameInfo {
currentPlayerIndex = (currentPlayerIndex+1) % civilizations.size
if(currentPlayerIndex==0){
turns++
if (turns % 10 == 0) { // every 10 turns add a barbarian in a random place
if (turns % 10 == 0 && !gameParameters.noBarbarians) { // every 10 turns add a barbarian in a random place
placeBarbarianUnit(null)
}
}

View file

@ -28,11 +28,11 @@ class NextTurnAutomation{
automateUnits(civInfo)
reassignWorkedTiles(civInfo)
trainSettler(civInfo)
civInfo.diplomaticIncidents.clear()
civInfo.popupAlerts.clear()
}
private fun buyBuildingOrUnit(civInfo: CivilizationInfo) {
//allow ai spending money to purchase building & unit. Buying staff has slightly lower priority than buying tech.
//allow AI spending money to purchase building & unit. Buying staff has slightly lower priority than buying tech.
for (city in civInfo.cities.sortedByDescending{ it.population.population }) {
val construction = city.cityConstructions.getCurrentConstruction()
if (construction.canBePurchased()

View file

@ -4,8 +4,8 @@ import com.badlogic.gdx.graphics.Color
import com.unciv.logic.GameInfo
import com.unciv.logic.automation.UnitAutomation
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.diplomacy.DiplomaticIncident
import com.unciv.logic.civilization.diplomacy.DiplomaticIncidentType
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.unit.UnitType
import java.util.*
@ -162,6 +162,7 @@ class Battle(val gameInfo:GameInfo) {
private fun conquerCity(city: CityInfo, attacker: ICombatant) {
val enemyCiv = city.civInfo
attacker.getCivInfo().addNotification("We have conquered the city of [${city.name}]!",city.location, Color.RED)
attacker.getCivInfo().popupAlerts.add(PopupAlert(AlertType.CityConquered,city.name))
city.getCenterTile().apply {
if(militaryUnit!=null) militaryUnit!!.destroy()
@ -185,6 +186,9 @@ class Battle(val gameInfo:GameInfo) {
city.moveToCiv(attacker.getCivInfo())
city.resistanceCounter = city.population.population
city.workedTiles = hashSetOf() //reassign 1st working tile
city.population.specialists.clear()
city.population.autoAssignPopulation()
city.cityStats.update()
}
@ -194,7 +198,7 @@ class Battle(val gameInfo:GameInfo) {
for(civ in gameInfo.civilizations)
civ.addNotification("The civilization of [${enemyCiv.civName}] has been destroyed!", null, Color.RED)
enemyCiv.getCivUnits().forEach { it.destroy() }
attacker.getCivInfo().diplomaticIncidents.add(DiplomaticIncident(enemyCiv.civName,DiplomaticIncidentType.Defeated))
attacker.getCivInfo().popupAlerts.add(PopupAlert(AlertType.Defeated,enemyCiv.civName))
}
else if(enemyCiv.cities.isNotEmpty()){
enemyCiv.cities.first().cityConstructions.addBuilding("Palace") // relocate palace

View file

@ -1,6 +1,7 @@
package com.unciv.logic.battle
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.unit.UnitType
import kotlin.math.max
@ -88,6 +89,8 @@ class BattleDamage{
val modifiers = getGeneralModifiers(attacker, defender)
if(attacker is MapUnitCombatant) {
modifiers.putAll(getTileSpecificModifiers(attacker,defender.getTile()))
val defenderTile = defender.getTile()
val isDefenderInRoughTerrain = defenderTile.baseTerrain=="Hill" || defenderTile.terrainFeature == "Forest" || defenderTile.terrainFeature == "Jungle"
for (BDM in getBattleDamageModifiersOfUnit(attacker.unit)) {
@ -113,6 +116,7 @@ class BattleDamage{
else modifiers["Attacker Bonus"] = bonus
}
}
else if (attacker is CityCombatant) {
if (attacker.getCivInfo().policies.isAdopted("Oligarchy") && attacker.city.getCenterTile().militaryUnit != null)
modifiers["Oligarchy"] = 0.5f
@ -140,7 +144,9 @@ class BattleDamage{
val modifiers = getGeneralModifiers(defender, attacker)
if (!(defender.unit.hasUnique("No defensive terrain bonus"))) {
modifiers.putAll(getTileSpecificModifiers(defender, defender.getTile()))
if (!defender.unit.hasUnique("No defensive terrain bonus")) {
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus
}
@ -172,6 +178,17 @@ class BattleDamage{
return modifiers
}
private fun getTileSpecificModifiers(unit: MapUnitCombatant, tile: TileInfo): HashMap<String,Float> {
val modifiers = HashMap<String,Float>()
val isFriendlyTerritory = tile.getOwner()!=null && !unit.getCivInfo().isAtWarWith(tile.getOwner()!!)
if(isFriendlyTerritory && unit.getCivInfo().getBuildingUniques().contains("+15% combat strength for units fighting in friendly territory"))
modifiers["Himeji Castle"] = 0.15f
if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory"))
modifiers["Foreign Land"] = 0.2f
return modifiers
}
private fun modifiersToMultiplicationBonus(modifiers: HashMap<String, Float>): Float {
// modifiers are like 0.1 for a 10% bonus, -0.1 for a 10% loss
var finalModifier = 1f

View file

@ -38,7 +38,7 @@ class CityConstructions {
fun getStats(): Stats {
val stats = Stats()
for (building in getBuiltBuildings())
stats.add(building.getStats(cityInfo.civInfo.policies.adoptedPolicies))
stats.add(building.getStats(cityInfo.civInfo))
stats.science += (cityInfo.getBuildingUniques().count { it == "+1 Science Per 2 Population" } * cityInfo.population.population / 2).toFloat()
return stats
}
@ -199,7 +199,7 @@ class CityConstructions {
cityInfo.civInfo.gold -= getConstruction(buildingName).getGoldCost(cityInfo.civInfo.policies.adoptedPolicies)
getConstruction(buildingName).postBuildEvent(this)
if (currentConstruction == buildingName) {
currentConstruction=""
currentConstruction = ""
chooseNextConstruction()
}
cityInfo.cityStats.update()

View file

@ -73,6 +73,7 @@ class CityInfo {
if (listOf("Forest", "Jungle", "Marsh").contains(tile.terrainFeature))
tile.terrainFeature = null
workedTiles = hashSetOf() //reassign 1st working tile
population.autoAssignPopulation()
cityStats.update()
}
@ -114,7 +115,9 @@ class CityInfo {
if(civInfo.policies.isAdopted("Facism")) amountToAdd*=2
if(civInfo.getNation().unique=="Strategic Resources provide +1 Production, and Horses, Iron and Uranium Resources provide double quantity"
&& resource.name in listOf("Horses","Iron","Uranium"))
amountToAdd*=2
amountToAdd *= 2
if(resource.name=="Oil" && civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity")
amountToAdd *= 2
}
if(resource.resourceType == ResourceType.Luxury
&& getBuildingUniques().contains("Provides 1 extra copy of each improved luxury resource near this City"))

View file

@ -34,7 +34,8 @@ class CityStats {
if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) {
val civInfo = cityInfo.civInfo
var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2.0
if(civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity") goldFromTradeRoute += 1
if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2
if (civInfo.getBuildingUniques().contains("Gold from all trade routes +25%")) goldFromTradeRoute *= 1.25 // Machu Pichu speciality
stats.gold += goldFromTradeRoute.toFloat()
}

View file

@ -7,8 +7,6 @@ import com.unciv.UnCivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
import com.unciv.logic.civilization.diplomacy.DiplomaticIncident
import com.unciv.logic.civilization.diplomacy.DiplomaticIncidentType
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.logic.map.BFS
import com.unciv.logic.map.MapUnit
@ -63,7 +61,7 @@ class CivilizationInfo {
var victoryManager=VictoryManager()
var diplomacy = HashMap<String, DiplomacyManager>()
var notifications = ArrayList<Notification>()
val diplomaticIncidents = ArrayList<DiplomaticIncident>()
val popupAlerts = ArrayList<PopupAlert>()
// if we only use lists, and change the list each time the cities are changed,
// we won't get concurrent modification exceptions.
@ -296,12 +294,13 @@ class CivilizationInfo {
fun meetCivilization(otherCiv: CivilizationInfo) {
diplomacy[otherCiv.civName] = DiplomacyManager(this, otherCiv.civName)
.apply { diplomaticStatus = DiplomaticStatus.Peace }
otherCiv.diplomaticIncidents.add(DiplomaticIncident(civName, DiplomaticIncidentType.FirstContact))
otherCiv.popupAlerts.add(PopupAlert(AlertType.FirstContact,civName))
otherCiv.diplomacy[civName] = DiplomacyManager(otherCiv, civName)
.apply { diplomaticStatus = DiplomaticStatus.Peace }
diplomaticIncidents.add(DiplomaticIncident(otherCiv.civName, DiplomaticIncidentType.FirstContact))
popupAlerts.add(PopupAlert(AlertType.FirstContact,otherCiv.civName))
}
override fun toString(): String {return civName} // for debug

View file

@ -0,0 +1,10 @@
package com.unciv.logic.civilization
enum class AlertType{
WarDeclaration,
Defeated,
FirstContact,
CityConquered
}
class PopupAlert (val type:AlertType, val value:String)

View file

@ -1,7 +1,9 @@
package com.unciv.logic.civilization.diplomacy
import com.badlogic.gdx.graphics.Color
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.trade.Trade
import com.unciv.logic.trade.TradeType
import com.unciv.models.Counter
@ -97,9 +99,11 @@ class DiplomacyManager() {
fun declareWar(){
diplomaticStatus = DiplomaticStatus.War
otherCiv().diplomacy[civInfo.civName]!!.diplomaticStatus = DiplomaticStatus.War
otherCiv().addNotification("[${civInfo.civName}] has declared war on us!",null, Color.RED)
otherCiv().diplomaticIncidents.add(DiplomaticIncident(civInfo.civName,DiplomaticIncidentType.WarDeclaration))
val otherCiv = otherCiv()
otherCiv.diplomacy[civInfo.civName]!!.diplomaticStatus = DiplomaticStatus.War
otherCiv.addNotification("[${civInfo.civName}] has declared war on us!",null, Color.RED)
otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration,civInfo.civName))
}
//endregion
}

View file

@ -1,5 +0,0 @@
package com.unciv.logic.civilization.diplomacy
import com.unciv.logic.trade.Trade
class DiplomaticIncident(val civName:String, val type: DiplomaticIncidentType, val trade: Trade?=null)

View file

@ -1,7 +0,0 @@
package com.unciv.logic.civilization.diplomacy
enum class DiplomaticIncidentType{
WarDeclaration,
Defeated,
FirstContact
}

View file

@ -176,6 +176,7 @@ class MapUnit {
fun isIdle(): Boolean {
if (currentMovement == 0f) return false
if (name == "Worker" && getTile().improvementInProgress != null) return false
if (hasUnique("Can construct roads") && currentTile.improvementInProgress=="Road") return false
if (isFortified()) return false
if (action=="Sleep") return false
return true
@ -301,6 +302,7 @@ class MapUnit {
private fun doPostTurnAction() {
if (name == "Worker" && getTile().improvementInProgress != null) workOnImprovement()
if(hasUnique("Can construct roads") && currentTile.improvementInProgress=="Road") workOnImprovement()
if(currentMovement== getMaxMovement().toFloat()
&& isFortified()){
val currentTurnsFortified = getFortificationTurns()

View file

@ -21,6 +21,7 @@ enum class MapType {
File
}
class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
var landProb = 0.55f
var numSmooth = 4
@ -28,7 +29,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
constructor(type: MapType): this() {
mapType = type
if (mapType < MapType.Default) {
if (mapType != MapType.Default && mapType !=MapType.Pangaea) {
mapType = MapType.Default
}
}
@ -77,6 +78,8 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
for(tile in mapToReturn.values) randomizeTile(tile,mapToReturn)
randomizeStrategicResources(mapToReturn,distance)
return mapToReturn
}
@ -227,6 +230,8 @@ class PerlinNoiseRandomMapGenerator:SeedRandomMapGenerator(){
for(tile in mapToReturn.values) randomizeTile(tile,mapToReturn)
randomizeStrategicResources(mapToReturn,distance)
return mapToReturn
}
@ -333,6 +338,7 @@ open class SeedRandomMapGenerator : RandomMapGenerator() {
for (entry in map) randomizeTile(entry.value, mapToReturn)
setWaterTiles(mapToReturn)
randomizeStrategicResources(mapToReturn,distance)
return mapToReturn
}
@ -357,15 +363,6 @@ open class SeedRandomMapGenerator : RandomMapGenerator() {
}
expandAreas(areas, map)
// 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]!!.baseTerrain = ""
// }
// }
expandAreas(areas, map)
}
@ -450,7 +447,7 @@ open class RandomMapGenerator {
var resource: TileResource? = null
when {
Math.random() < 1 / 5f -> resource = getRandomResource(tileResources, ResourceType.Bonus)
Math.random() < 1 / 15f -> resource = getRandomResource(tileResources, ResourceType.Bonus)
Math.random() < 1 / 15f -> resource = getRandomResource(tileResources, ResourceType.Strategic)
Math.random() < 1 / 15f -> resource = getRandomResource(tileResources, ResourceType.Luxury)
}
@ -504,4 +501,40 @@ open class RandomMapGenerator {
addRandomResourceToTile(tileInfo)
maybeAddAncientRuins(tileInfo)
}
fun randomizeStrategicResources(mapToReturn: HashMap<String, TileInfo>,distance: Int) {
for(tile in mapToReturn.values)
if(tile.resource!=null && tile.getTileResource().resourceType==ResourceType.Strategic)
tile.resource=null
for(resource in GameBasics.TileResources.values.filter { it.resourceType==ResourceType.Strategic }){
val suitableTiles = mapToReturn.values
.filter { it.resource==null && resource.terrainsCanBeFoundOn.contains(it.getLastTerrain().name) }
val numberOfResources = mapToReturn.count() / 100
val locations = chooseSpreadOutLocations(numberOfResources,suitableTiles, distance)
for(location in locations) location.resource = resource.name
}
}
fun chooseSpreadOutLocations(numberOfResources: Int, suitableTiles: List<TileInfo>, initialDistance:Int): ArrayList<TileInfo> {
for(distanceBetweenResources in initialDistance downTo 1){
var availableTiles = suitableTiles.toList()
val chosenTiles = ArrayList<TileInfo>()
for(i in 1..numberOfResources){
if(availableTiles.isEmpty()) break
val chosenTile = availableTiles.random()
availableTiles = availableTiles.filter { it.arialDistanceTo(chosenTile)>distanceBetweenResources }
chosenTiles.add(chosenTile)
}
if(chosenTiles.size == numberOfResources) return chosenTiles
}
throw Exception("ArgleBargle")
}
}

View file

@ -43,7 +43,6 @@ class TileMap {
mapValues = CelluarAutomataRandomMapGenerator(newGameParameters.mapType).generateMap(newGameParameters.mapRadius).values
tileList.addAll(mapValues)
// tileList.addAll(AlexanderRandomMapGenerator().generateMap(distance,0.8f).values)
setTransients()
}

View file

@ -2,6 +2,7 @@ package com.unciv.models.gamebasics
import com.unciv.logic.city.CityConstructions
import com.unciv.logic.city.IConstruction
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.tech.Technology
import com.unciv.models.stats.NamedStats
import com.unciv.models.stats.Stats
@ -10,7 +11,7 @@ import com.unciv.ui.utils.getRandom
class Building : NamedStats(), IConstruction{
override val description: String
get() = getDescription(false, hashSetOf())
get() = getDescription(false, null)
var requiredTech: String? = null
@ -50,7 +51,7 @@ class Building : NamedStats(), IConstruction{
fun getShortDescription(): String { // should fit in one line
val infoList= mutableListOf<String>()
val str = getStats(hashSetOf()).toString()
val str = getStats(null).toString()
if(str.isNotEmpty()) infoList += str
if(percentStatBonus!=null){
for(stat in percentStatBonus!!.toHashMap())
@ -70,8 +71,8 @@ class Building : NamedStats(), IConstruction{
return infoList.joinToString()
}
fun getDescription(forBuildingPickerScreen: Boolean, adoptedPolicies: HashSet<String>): String {
val stats = getStats(adoptedPolicies)
fun getDescription(forBuildingPickerScreen: Boolean, civInfo: CivilizationInfo?): String {
val stats = getStats(civInfo)
val stringBuilder = StringBuilder()
if(uniqueTo!=null) stringBuilder.appendln("Unique to [$uniqueTo], replaces [$replaces]".tr())
if (!forBuildingPickerScreen) stringBuilder.appendln("{Cost}: $cost".tr())
@ -118,35 +119,44 @@ class Building : NamedStats(), IConstruction{
}
val cultureBuildings = hashSetOf("Monument", "Temple", "Monastery")
fun getStats(adoptedPolicies: HashSet<String>): Stats {
fun getStats(civInfo: CivilizationInfo?): Stats {
val stats = this.clone()
if (adoptedPolicies.contains("Organized Religion") && cultureBuildings.contains(name))
stats.happiness += 1
if(civInfo != null) {
val adoptedPolicies = civInfo.policies.adoptedPolicies
if (adoptedPolicies.contains("Organized Religion") && cultureBuildings.contains(name))
stats.happiness += 1
if (adoptedPolicies.contains("Free Religion") && cultureBuildings.contains(name))
stats.culture += 1f
if (adoptedPolicies.contains("Free Religion") && cultureBuildings.contains(name))
stats.culture += 1f
if (adoptedPolicies.contains("Entrepreneurship") && hashSetOf("Mint", "Market", "Bank", "Stock Market").contains(name))
stats.science += 1f
if (adoptedPolicies.contains("Entrepreneurship") && hashSetOf("Mint", "Market", "Bank", "Stock Market").contains(name))
stats.science += 1f
if (adoptedPolicies.contains("Humanism") && hashSetOf("University", "Observatory", "Public School").contains(name))
stats.happiness += 1f
if (adoptedPolicies.contains("Humanism") && hashSetOf("University", "Observatory", "Public School").contains(name))
stats.happiness += 1f
if (adoptedPolicies.contains("Theocracy") && name == "Temple")
percentStatBonus = Stats().apply { gold=10f }
if (adoptedPolicies.contains("Theocracy") && name == "Temple")
percentStatBonus = Stats().apply { gold = 10f }
if (adoptedPolicies.contains("Free Thought") && name == "University")
percentStatBonus!!.science = 50f
if (adoptedPolicies.contains("Free Thought") && name == "University")
percentStatBonus!!.science = 50f
if (adoptedPolicies.contains("Rationalism Complete") && !isWonder && stats.science > 0)
stats.gold += 1f
if (adoptedPolicies.contains("Rationalism Complete") && !isWonder && stats.science > 0)
stats.gold += 1f
if (adoptedPolicies.contains("Constitution") && isWonder)
stats.culture += 2f
if (adoptedPolicies.contains("Constitution") && isWonder)
stats.culture += 2f
if(adoptedPolicies.contains("Autocracy Complete") && cityStrength>0)
stats.happiness+=1
if (adoptedPolicies.contains("Autocracy Complete") && cityStrength > 0)
stats.happiness += 1
if (name == "Castle" && civInfo.getBuildingUniques().contains("+1 happiness, +2 culture and +3 gold from every Castle")){
stats.happiness+=1
stats.culture+=2
stats.gold+=3
}
}
return stats
}

View file

@ -60,6 +60,12 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski
textList += " "+unique.tr()
if (building.maintenance != originalBuilding.maintenance)
textList += " {Maintenance} " + building.maintenance + " vs " + originalBuilding.maintenance
if(building.cost != originalBuilding.cost)
textList += " {Cost} " + building.cost + " vs " + originalBuilding.cost
if(building.cityStrength != originalBuilding.cityStrength)
textList += " {City strength} " + building.cityStrength+ " vs " + originalBuilding.cityStrength
if(building.cityHealth!= originalBuilding.cityHealth)
textList += " {City health} " + building.cityHealth+ " vs " + originalBuilding.cityHealth
textList+=""
}
@ -76,10 +82,13 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski
textList+= " {Range} " + unit.range+ " vs " + originalUnit.range
if (unit.movement!= originalUnit.movement)
textList+= " {Movement} " + unit.movement+ " vs " + originalUnit.movement
if(originalUnit.requiredResource!=null && unit.requiredResource==null)
textList+= " "+"[${originalUnit.requiredResource}] not required".tr()
for(unique in unit.uniques.filterNot { it in originalUnit.uniques })
textList += " "+Translations.translateBonusOrPenalty(unique)
for(promotions in unit.promotions.filter { it !in originalUnit.promotions})
textList += " "+promotions.tr()
for(promotion in unit.promotions.filter { it !in originalUnit.promotions})
textList += " "+promotion.tr()+ " ("+Translations.translateBonusOrPenalty(GameBasics.UnitPromotions[promotion]!!.effect)+")"
textList+=""
}

View file

@ -2,10 +2,7 @@ package com.unciv.ui
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.Skin
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
import com.badlogic.gdx.utils.Array
import com.unciv.GameStarter
@ -74,17 +71,50 @@ class NewGameScreen: PickerScreen(){
val newGameOptionsTable = Table()
newGameOptionsTable.skin = skin
addMapTypeSizeAndFile(newGameOptionsTable)
addNumberOfHumansAndEnemies(newGameOptionsTable)
addDifficultySelectBox(newGameOptionsTable)
val noBarbariansCheckbox = CheckBox("No barbarians",skin)
noBarbariansCheckbox.isChecked=newGameParameters.noBarbarians
noBarbariansCheckbox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {
newGameParameters.noBarbarians = noBarbariansCheckbox.isChecked
}
})
newGameOptionsTable.add(noBarbariansCheckbox).colspan(2).row()
rightSideButton.enable()
rightSideButton.setText("Start game!".tr())
rightSideButton.onClick {
Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked!
rightSideButton.disable()
rightSideButton.setText("Working...".tr())
thread { // Creating a new game can take a while and we don't want ANRs
newGame = GameStarter().startNewGame(newGameParameters)
}
}
newGameOptionsTable.pack()
return newGameOptionsTable
}
private fun addMapTypeSizeAndFile(newGameOptionsTable: Table) {
newGameOptionsTable.add("{Map type}:".tr())
val mapTypes = LinkedHashMap<String, MapType>()
for (type in MapType.values()) {
if(type==MapType.File && GameSaver().getMaps().isEmpty()) continue
if (type == MapType.File && GameSaver().getMaps().isEmpty()) continue
mapTypes[type.toString()] = type
}
val mapFileLabel = "{Map file}:".toLabel()
val mapFileSelectBox = getMapFileSelectBox()
mapFileLabel.isVisible=false
mapFileSelectBox.isVisible=false
mapFileLabel.isVisible = false
mapFileSelectBox.isVisible = false
val mapTypeSelectBox = TranslatedSelectBox(mapTypes.keys, newGameParameters.mapType.toString(), skin)
@ -98,13 +128,13 @@ class NewGameScreen: PickerScreen(){
worldSizeSelectBox.isVisible = false
worldSizeLabel.isVisible = false
mapFileSelectBox.isVisible = true
mapFileLabel.isVisible=true
mapFileLabel.isVisible = true
newGameParameters.mapFileName = mapFileSelectBox.selected
} else {
worldSizeSelectBox.isVisible = true
worldSizeLabel.isVisible = true
mapFileSelectBox.isVisible = false
mapFileLabel.isVisible=false
mapFileLabel.isVisible = false
newGameParameters.mapFileName = null
}
}
@ -117,8 +147,9 @@ class NewGameScreen: PickerScreen(){
newGameOptionsTable.add(mapFileLabel)
newGameOptionsTable.add(mapFileSelectBox).pad(10f).row()
}
private fun addNumberOfHumansAndEnemies(newGameOptionsTable: Table) {
newGameOptionsTable.add("{Number of human players}:".tr())
val humanPlayers = SelectBox<Int>(skin)
val humanPlayersArray = Array<Int>()
@ -131,7 +162,7 @@ class NewGameScreen: PickerScreen(){
newGameOptionsTable.add("{Number of enemies}:".tr())
val enemiesSelectBox = SelectBox<Int>(skin)
val enemiesArray = Array<Int>()
(0..GameBasics.Nations.size-1).forEach { enemiesArray.add(it) }
(0..GameBasics.Nations.size - 1).forEach { enemiesArray.add(it) }
enemiesSelectBox.items = enemiesArray
enemiesSelectBox.selected = newGameParameters.numberOfEnemies
newGameOptionsTable.add(enemiesSelectBox).pad(10f).row()
@ -153,32 +184,17 @@ class NewGameScreen: PickerScreen(){
removeExtraHumanNations(humanPlayers)
}
})
}
private fun addDifficultySelectBox(newGameOptionsTable: Table) {
newGameOptionsTable.add("{Difficulty}:".tr())
val difficultySelectBox = TranslatedSelectBox(GameBasics.Difficulties.keys, newGameParameters.difficulty , skin)
val difficultySelectBox = TranslatedSelectBox(GameBasics.Difficulties.keys, newGameParameters.difficulty, skin)
difficultySelectBox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {
newGameParameters.difficulty = difficultySelectBox.selected.value
}
})
newGameOptionsTable.add(difficultySelectBox).pad(10f).row()
rightSideButton.enable()
rightSideButton.setText("Start game!".tr())
rightSideButton.onClick {
Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked!
rightSideButton.disable()
rightSideButton.setText("Working...".tr())
thread {
// Creating a new game can tke a while and we don't want ANRs
newGame = GameStarter().startNewGame(newGameParameters)
}
}
newGameOptionsTable.pack()
return newGameOptionsTable
}
private fun getMapFileSelectBox(): SelectBox<String> {

View file

@ -60,7 +60,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
wonderDetailsTable.clear()
else{
val detailsString = building.getDescription(true,
cityScreen.city.civInfo.policies.adoptedPolicies)
cityScreen.city.civInfo)
wonderDetailsTable.add(detailsString.toLabel().apply { setWrap(true)})
.width(cityScreen.stage.width/4 - 2*pad ).row() // when you set wrap, then you need to manually set the size of the label
if(!building.isWonder) {

View file

@ -18,6 +18,7 @@ import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable
class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin){
var constructionScrollPane:ScrollPane?=null
var lastConstruction = ""
private fun getProductionButton(construction: String, buttonText: String, rejectionReason: String=""): Table {
val pickProductionButton = Table()
@ -35,6 +36,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
if(rejectionReason=="") {
pickProductionButton.onClick {
lastConstruction = cityScreen.city.cityConstructions.currentConstruction
cityScreen.city.cityConstructions.currentConstruction = construction
cityScreen.city.cityStats.update()
cityScreen.update()
@ -131,7 +133,8 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
}
private fun addCurrentConstructionTable(city: CityInfo) {
val construction = city.cityConstructions.getCurrentConstruction()
val cityConstructions = city.cityConstructions
val construction = cityConstructions.getCurrentConstruction()
row()
val purchaseConstructionButton: TextButton
@ -140,7 +143,9 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
purchaseConstructionButton = TextButton("Buy for [$buildingGoldCost] gold".tr(), CameraStageBaseScreen.skin)
purchaseConstructionButton.onClick("coin") {
YesNoPopupTable("Would you like to purchase [${construction.name}] for [$buildingGoldCost] gold?".tr(), {
city.cityConstructions.purchaseBuilding(construction.name)
cityConstructions.purchaseBuilding(construction.name)
if(lastConstruction!="" && cityConstructions.getConstruction(lastConstruction).isBuildable(cityConstructions))
city.cityConstructions.currentConstruction = lastConstruction
update()
}, cityScreen)
}
@ -170,7 +175,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
if (currentConstruction is BaseUnit)
description = currentConstruction.getDescription(true)
else if (currentConstruction is Building)
description = currentConstruction.getDescription(true, city.civInfo.policies.adoptedPolicies)
description = currentConstruction.getDescription(true, city.civInfo)
else description = currentConstruction.description.tr()
val descriptionLabel = description.toLabel()

View file

@ -93,8 +93,9 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
group.addActor(image)
val secondaryColor = cityConstructions.cityInfo.civInfo.getNation().getSecondaryColor()
if(cityConstructions.getCurrentConstruction() !is SpecialConstruction) {
val turnsToConstruction = cityConstructions.turnsToConstruction(cityConstructions.currentConstruction)
val cityCurrentConstruction = cityConstructions.getCurrentConstruction()
if(cityCurrentConstruction !is SpecialConstruction) {
val turnsToConstruction = cityConstructions.turnsToConstruction(cityCurrentConstruction.name)
val label = turnsToConstruction.toString().toLabel()
label.setFontColor(secondaryColor)
label.setFontSize(10)

View file

@ -3,6 +3,7 @@ package com.unciv.ui.tilegroups
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.utils.Align
import com.unciv.UnCivGame
@ -49,6 +50,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
var populationImage: Image? = null //reuse for acquire icon
private val roadImages = HashMap<TileInfo, RoadImage>()
private val borderImages = HashMap<TileInfo, List<Image>>() // map of neighboring tile to border images
val unitLayerGroup = Group().apply { isTransform=false; setSize(groupSize,groupSize);touchable=Touchable.disabled }
protected var civilianUnitImage: UnitGroup? = null
protected var militaryUnitImage: UnitGroup? = null
@ -71,6 +74,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
this.addActor(baseLayerGroup)
this.addActor(featureLayerGroup)
this.addActor(miscLayerGroup)
this.addActor(unitLayerGroup)
this.addActor(circleCrosshairFogLayerGroup)
updateTileImage(false)
@ -426,7 +430,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
newImage.blackSpinningCircle = ImageGetter.getCircle()
.apply { rotation= oldUnitGroup.blackSpinningCircle!!.rotation}
}
miscLayerGroup.addActor(newImage)
unitLayerGroup.addActor(newImage)
newImage.center(this)
newImage.y += yFromCenter

View file

@ -30,6 +30,7 @@ class TileGroupMap<T: TileGroup>(tileGroups:Collection<T>, padding:Float): Group
val baseLayers = ArrayList<Group>()
val featureLayers = ArrayList<Group>()
val miscLayers = ArrayList<Group>()
val unitLayers = ArrayList<Group>()
val circleCrosshairFogLayers = ArrayList<Group>()
for(group in tileGroups.sortedByDescending { it.tileInfo.position.x + it.tileInfo.position.y }){
@ -37,13 +38,15 @@ class TileGroupMap<T: TileGroup>(tileGroups:Collection<T>, padding:Float): Group
baseLayers.add(group.baseLayerGroup.apply { setPosition(group.x,group.y) })
featureLayers.add(group.featureLayerGroup.apply { setPosition(group.x,group.y) })
miscLayers.add(group.miscLayerGroup.apply { setPosition(group.x,group.y) })
unitLayers.add(group.unitLayerGroup.apply { setPosition(group.x,group.y) })
circleCrosshairFogLayers.add(group.circleCrosshairFogLayerGroup.apply { setPosition(group.x,group.y) })
}
for(group in baseLayers) addActor(group)
for(group in featureLayers) addActor(group)
for(group in miscLayers) addActor(group)
for(group in circleCrosshairFogLayers) addActor(group)
for(group in tileGroups) addActor(group) // The above layers are for the visual layers, this is for the cli
for(group in tileGroups) addActor(group) // The above layers are for the visual layers, this is for the clickability
for(group in unitLayers) addActor(group) // Aaand units above everything else.
// there are tiles "below the zero",

View file

@ -8,11 +8,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.UnCivGame
import com.unciv.logic.GameSaver
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.diplomacy.DiplomaticIncident
import com.unciv.logic.civilization.diplomacy.DiplomaticIncidentType
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.Nation
import com.unciv.models.gamebasics.tile.ResourceType
import com.unciv.models.gamebasics.tr
import com.unciv.models.gamebasics.unit.UnitType
@ -171,8 +172,8 @@ class WorldScreen : CameraStageBaseScreen() {
else if(currentPlayerCiv.greatPeople.freeGreatPeople>0) game.screen = GreatPersonPickerScreen()
if(game.screen==this && !tutorials.isTutorialShowing
&& currentPlayerCiv.diplomaticIncidents.any() && !DiplomaticIncidentPopup.isOpen){
DiplomaticIncidentPopup(this,currentPlayerCiv.diplomaticIncidents.first())
&& currentPlayerCiv.popupAlerts.any() && !AlertPopup.isOpen){
AlertPopup(this,currentPlayerCiv.popupAlerts.first())
}
}
@ -329,43 +330,59 @@ class WorldScreen : CameraStageBaseScreen() {
}
class DiplomaticIncidentPopup(val worldScreen: WorldScreen, val diplomaticIncident: DiplomaticIncident):PopupTable(worldScreen){
class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert):PopupTable(worldScreen){
fun getCloseButton(text:String): TextButton {
val button = TextButton(text.tr(), skin)
button.onClick { close() }
return button
}
init {
val otherCiv = worldScreen.gameInfo.getCivilization(diplomaticIncident.civName)
val translatedNation = otherCiv.getTranslatedNation()
fun addLeaderName(translatedNation:Nation){
val otherCivLeaderName = "[${translatedNation.leaderName}] of [${translatedNation.getNameTranslation()}]".tr()
add(otherCivLeaderName.toLabel())
addSeparator()
}
when(diplomaticIncident.type){
DiplomaticIncidentType.WarDeclaration -> {
init {
when(popupAlert.type){
AlertType.WarDeclaration -> {
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
addLeaderName(translatedNation)
addGoodSizedLabel(translatedNation.declaringWar).row()
val responseTable = Table()
responseTable.add(getCloseButton("You'll pay for this!"))
responseTable.add(getCloseButton("Very well."))
add(responseTable)
}
DiplomaticIncidentType.Defeated -> {
AlertType.Defeated -> {
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
addLeaderName(translatedNation)
addGoodSizedLabel(translatedNation.defeated).row()
add(getCloseButton("Farewell."))
}
DiplomaticIncidentType.FirstContact -> {
AlertType.FirstContact -> {
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
addLeaderName(translatedNation)
addGoodSizedLabel(translatedNation.introduction).row()
add(getCloseButton("A pleasure to meet you."))
}
AlertType.CityConquered -> {
addGoodSizedLabel("What would you like to do with the city?").row()
add(getCloseButton("Annex")).row()
add(TextButton("Raze",skin).onClick {
worldScreen.currentPlayerCiv.cities.first { it.name==popupAlert.value }.isBeingRazed=true
worldScreen.shouldUpdate=true
close()
})
}
}
open()
isOpen = true
}
fun close(){
worldScreen.currentPlayerCiv.diplomaticIncidents.remove(diplomaticIncident)
worldScreen.currentPlayerCiv.popupAlerts.remove(popupAlert)
isOpen = false
remove()
}

View file

@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Cell
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.unciv.UnCivGame
import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.*
@ -27,6 +28,7 @@ open class PopupTable(val screen: CameraStageBaseScreen): Table(CameraStageBaseS
fun addGoodSizedLabel(text: String): Cell<Label> {
val label = text.toLabel()
label.setWrap(true)
label.setAlignment(Align.center)
return add(label).width(screen.stage.width/2)
}
@ -43,7 +45,6 @@ class YesNoPopupTable(question:String, action:()->Unit,
if(!screen.hasPopupOpen) {
screen.hasPopupOpen=true
add(question.toLabel()).colspan(2).row()
add(TextButton("No".tr(), skin).onClick { close() })
add(TextButton("Yes".tr(), skin).onClick { close(); action() })
open()

View file

@ -5,6 +5,7 @@ import com.unciv.UnCivGame
import com.unciv.logic.automation.UnitAutomation
import com.unciv.logic.automation.WorkerAutomation
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.RoadStatus
import com.unciv.models.gamebasics.Building
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tr
@ -140,6 +141,14 @@ class UnitActions {
}
}
if(unit.hasUnique("Can construct roads") && tile.roadStatus==RoadStatus.None
&& tile.improvementInProgress != "Road"
&& unit.civInfo.tech.isResearched(GameBasics.TileImprovements["Road"]!!.techRequired!!))
actionList+=UnitAction("Construct road", unit.currentMovement >0){
tile.improvementInProgress="Road"
tile.turnsToImprovement=4
}
for(improvement in listOf("Fishing Boats","Oil well")) {
if (unit.hasUnique("May create improvements on water resources") && tile.resource != null
&& tile.improvement==null

View file

@ -45,6 +45,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
"Create Fishing Boats" -> return ImageGetter.getImprovementIcon("Fishing Boats")
"Create Oil well" -> return ImageGetter.getImprovementIcon("Oil well")
"Pillage" -> return ImageGetter.getImage("OtherIcons/Pillage")
"Construct road" -> return ImageGetter.getImprovementIcon("Road")
else -> return ImageGetter.getImage("OtherIcons/Star")
}
}