[MOD] Colonization: 2071

I managed to remove all references to luxury food (YIELD_GRAIN) in the code.

A few places use #ifdef USE_NOBLE_CLASS (which is automatically defined when compiling M:C)
Adding ifdefs ended up being messy so I restarted and made a new yield group called YieldGroup_Luxury_Food(). It made the code much cleaner and is really justified even though it only contains 0 or 1 yields (small group :lol:)

I stopped for a moment at hunting. The code was easy enough to add ifdef around, but I didn't want to do that. 2071 might want to hunt at some point and it should be accessable without messing with the other code I wrote in ifdefs.
I ended up writing this in YieldTypes
Code:
YIELD_FROM_ANIMALS = YIELD_GRAIN,
Yeah a new yield type just for hunting. The clever bit here is that it's written AFTER NUM_YIELD_TYPES meaning the game doesn't see it as a new unique yield like the others and it's not in the count of yields. At the same time it's assigned the same value as YIELD_GRAIN meaning the compiled code will be the same for M:C. 2071 sets it to NO_YIELD. The hunting code no longer uses YIELD_GRAIN, but instead it uses YIELD_FROM_ANIMALS and it only executes the code if YIELD_FROM_ANIMALS is different from NO_YIELD.
Now we can edit the enum for 2071 like this
Code:
YIELD_FROM_ANIMALS = YIELD_LUMBER,
and killing animals will provide lumber (that's some strange animals :eek::lol:)
Edit: that has to be trojan horses :lol:

This new addition gave me a new idea. We can define whatever yields we want without considering the hardcoded ones. At the bottom of the enum we can add the hardcoded.

Code:
YIELD_FOOD = YIELD_NUTRIENTS,
YIELD_LUMBER = YIELD_BIOPOLYMERS,
YIELD_STONE = YIELD_SILICATES,
You get the idea. Writing it that way the yield groups and other 2071 specific code can use the "real" names while the shared code still use the names it uses right now.
 
:w00t:DONE:rockon:

I added the 2071 yields from the plan and now Yields_Colonization_2071.h has 33 yields. That's just one less than M:C.

Spoiler :
YIELD_NUTRIENTS
YIELD_BIOPOLYMERS
YIELD_SILICATES
YIELD_BASE_METALS
YIELD_PRECIOUS_METALS
YIELD_ISOTOPES
YIELD_URANIUM
YIELD_RARE_EARTHS
YIELD_CRYSTALLOIDS
YIELD_TISSUE_SAMPLES
YIELD_YIELD_NUCLEIC_ACIDS
YIELD_AMINO_ACIDS
YIELD_MICROBES
YIELD_PROGENITOR_ARTIFACTS
YIELD_ALIEN_SPECIMENS
YIELD_ENCRYPTED_DATA
YIELD_OPIATES
YIELD_XENOTOXINS
YIELD_BOTANICALS
YIELD_HYDROCARBONS
YIELD_HALOGENS
YIELD_CORE_SAMPLES
YIELD_TOOLS
YIELD_WEAPONS
YIELD_HORSES
YIELD_TRADE_GOODS
YIELD_HAMMERS
YIELD_BELLS
YIELD_CROSSES
YIELD_EDUCATION
YIELD_IDEAS
YIELD_CULTURE
YIELD_GOLD

The yields will appear ingame in this order. Maybe they should be rearranged at some point. However that's a microscopic task in comparison.

Now the task goes to orlanth to see if it just works or if there are more issues. My prediction is that yields are ok now, but they might be other issues. We will look at them as they appear.

I missed the commits by one though. The final commit for this is number 101, not 100 :badcomp:

EDIT: added a txt file, which is a start for an xml file for yields. It's made by a script and lots of the numbers are more or less random. However the following should be correct for all: Type, Description, Civilopedia, bCargo, ColorType, UnitClass. I took a guess at tradescreen and think that one might work as well.
The layout should work just fine as I used the M:C xml file as template.

Alternatively they can be added one/a few at a time. In that case the yields in the DLL can be commented out. It's always easier to comment out code than to write it from scratch. That's why I decided to just add all of it now that the script I wrote for M:C was set to target 2071 anyway.
 

Attachments

Wow, that was faster than a Corvette with Fusion Cores & the Blockade Runner profession! :cool::scan:

Ok, I've downloaded the updated master branch DLL files into a new directory and started trying to build them following the steps in your post #278, starting by opening Medieval_Tech.vcxproj from that folder using Visual C++ 2010 Express. At first I couldn't figure how to select Clean Solution, but then I found it using this tutorial: http://vicidi.wordpress.com/2012/04/09/enabling-clean-solution-option-in-visual-basic-2010-express/

However when trying to clean or build I get the following error:
1>------ Clean started: Project: Medieval_Tech, Configuration: Colonization 2071 Win32 ------
1> 'nmake' is not recognized as an internal or external command,
1> operable program or batch file.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(33,5): error MSB3073: The command "set TARGET=Assert
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(33,5): error MSB3073: nmake clean" exited with code 9009.
========== Clean: 0 succeeded, 1 failed, 0 skipped ==========
Your Makefile from the main branch download is there and the fastdep.exe from the download is in the bin directory; I also tried adding jom.exe in the bin directory too but it didn't make any difference. There was actually already a Makefile.settings in the DLL_Source directory I downloaded from the main branch, but it just contains the following line
CUSTOM_CFLAGS =

So I tried going ahead and editing it to the following:
CUSTOM_CFLAGS = -DCOLONIZATION_2071
YOURMOD=c:\Program Files (x86)\Steam\steamapps\common\civilization iv colonization\Mods\Colonization 2071

But when trying to Build the solution get the following boost and python error.
1>------ Build started: Project: Medieval_Tech, Configuration: Colonization 2071 Win32 ------
1>
1> Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1>EXEC : FATAL error : Failed to locate boost and python
1> The system cannot find the path specified.
1> The system cannot find the path specified.
1> Error running fastdep.
1> Assert-fast causes this issue if Assert or Assert-fast has never been compiled before.
1> It is safe to ignore this error in that case, but only in that case!
1> _precompile.cpp
1>c:\Users\DR\Desktop\Medieval_Tech-master\Medieval_Tech-master\DLL_Sources\CvGameCoreDLL.h(159): fatal error C1083: Cannot open include file: 'boost/python/list.hpp': No such file or directory
1>NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003\bin\cl.exe"' : return code '0x2'
1> Stop.
1> Access is denied.
Is there something else I should be trying? :confused: sorry I'm such a newbie when it comes to DLL and compiling:blush:
 
We could make a long list of names to use for ships. HMS Warrior, HMS Dreadnought, HMS Beagle, USS Enterprise, USS Nautilus, IJN Yamato and Yamal.
I think the list can quickly become rather long. In a way I'm a bit surprised at that list as I just wrote ship names I remember. It turns out I know quite a number of ships as this is just a fraction of those I know
lol there at least I'm on the same page with you, as author of the fantastically obscure Historic Ship Names Modcomp :king:

It can assign random names from nation-specific arrays to ships using python - I know that's in Kailric's Pirates mod too; but I think RaR brought shipnames directly into civilizationinfos.xml. I think I had already extracted some shipname lists for several of the 2071 superpowers, I'll see if I can dig it up somewhere :p

edit: here it is.. now that's enough shipnames to spend all the Base Metals in the universe constructing :lol::borg:
Spoiler :
#shipname modcomp
def NameGen(self, unit):
pPlayer = gc.getPlayer(unit.getOwner())
pCiv = pPlayer.getCivilizationType()
sFull = "test"
lName = ["test1","test2"]
if pCiv == gc.getInfoTypeForString('CIVILIZATION_SPAIN') or pCiv == gc.getInfoTypeForString('CIVILIZATION_SPAIN_EUROPE'):
lName = ["Abraham Lincoln","Alabama","Alaska","Albany","Albuquerque","Alexandria","Annapolis","Antietam","Anzio","Ardent","Arleigh Burke","Asheville","Ashland","Avenger","Bainbridge","Schwartzenegger","Bataan","Benfold","Blue Ridge","Boise","Bonhomme Richard","Boone","Boxer","Bremerton","Buffalo","Bulkeley","Bunker Hill","Cape St. George","Carl Vinson","Carney","Carr","Carter Hall","Chafee","Champion","Chancellorsville","Charlotte","Cheyenne","Chicago","Chief","Chinook","Corpus Christi","Cole","Columbia","Columbus","Comstock","Connecticut","Constitution","Dallas","Decatur","Defender","Denver","Devastator","Dewey","Dextrous","Donald Cook","Dwight D. Eisenhower","Elrod","Billy Graham","Emory S. Land","Enterprise","Essex","Farragut","Firebolt","Fitzgerald","Florida","Ford","Forrest Sherman","Fort McHenry","Pat Robertson","Ross Perot","Freedom","Gary","George Washington","George H.W. Bush","Georgia","Germantown","Gettysburg","Gladiator","Gonzalez","Gravely","Green Bay","Greeneville","Gridley","Guardian","Gunston Hall","Halsey","Halliburton","Hampton","Harpers Ferry","Harry S. Truman","Hartford","Hawaii","Helena","Henry M. Jackson","Higgins","Hopper","Houston","Howard","Culver City","Hurricane","Independence","Ingraham","Iwo Jima","Jacksonville","James E. Williams","Jason Dunham","Jefferson City","Jimmy Carter","John C. Stennis","John L. Hall","John Paul Jones","John S. McCain","Kauffman","Kearsarge","Kentucky","Key West","Kidd","Klakring","La Jolla","Laboon","Lake Champlain","Lake Erie","Lassen","Leyte Gulf","Louisiana","Louisville","Mahan","Maine","Makin Island","Maryland","Mason","McCampbell","McClusky","McFaul","Mesa Verde","Miami","Michigan","Milius","Missouri","Mitscher","Mobile Bay","Momsen","Monsoon","Monterey","Montpelier","Mount Whitney","Mustin","Nebraska","Nevada","New Hampshire","New Mexico","New Orleans","New York","Newport News","Nicholas","Nimitz","Norfolk","Normandy","North Carolina","O'Kane","Oak Hill","Ohio","Oklahoma City","Olympia","Austin","Pasadena","Patriot","Paul Hamilton","Pearl Harbor","Wake Island","Pennsylvania","Guantanamo,"Pinckney","Pioneer","Pittsburgh","Ensenada","Port Royal","Porter","Preble","Princeton","Providence","Pueblo","Ramage","Rentz","Reuben James","Rhode Island","Robert G. Bradley","Rodney M. Davis","Ronald Reagan","Roosevelt","Ross","Rushmore","Russell","Sampson","Samuel B. Roberts","San Antonio","San Francisco","San Jacinto","San Juan","Santa Fe","Scout","Scranton","Seawolf","Sentry","Shiloh","Shoup","Simpson","Sirocco","Springfield","Spruance","Squall","Stephen W. Groves","Sterett","Stethem","Stockdale","Stout","Taylor","Tempest","Tennessee","Texas","Oklahoma","Missouri","Ohio","Illinois","Nebraska","Nevada","Florida","Georgia","Sascatchewan","Alberta","Theodore Roosevelt","Thunderbolt","Toledo","Topeka","Tortuga","Tucson","Typhoon","Vicksburg","Virginia","Warrior","Wasp","Wayne E. Meyer","West Virginia","Wyoming","Mexico City","Yucatan","Ottawa","Ontario","Newfoundland","Quebec","Los Angeles","Dearborn","New York","Vancouver","Oprah Winfrey","Puerto Rico"]
elif pCiv == gc.getInfoTypeForString('CIVILIZATION_ENGLAND') or pCiv == gc.getInfoTypeForString('CIVILIZATION_ENGLAND_EUROPE'):
lName = ["Mao Zedong","Deng Xiaoping","Jiangwei","Jianghu","Luhai","Guangzhou","Lanzhou","Hua Guofeng","Hu Yaobang","Jiang Zemin","Hu Jintao","Xiang Zhongfa","Wen Jiabao","Li Kequiang","Zhou Yongkang","Xu Caihou","Datong","Shenfeng","Dongfeng","Haifeng","Taifeng","Weifeng","Hongfeng","Dahan","Haishi","Haiying","Haipeng","Haixiang","Haidan","Haibao","Guolong","Tianlong","Yunlong","Huayang","Qingyang","Yueyang","Kunyang","Zhenghe","Hechuan","Hezhong","Changjiang","Jinjiang","Taishan","Hengshan","Yongchuan","Yongshan","Yongcheng","Yingshan","Yinghui","Wuxing","Guangxing","Longxing","Rongxing","Jiuxing","Qiuxing","Hanyang","Hanlong"]
elif pCiv == gc.getInfoTypeForString('CIVILIZATION_JAPAN') or pCiv == gc.getInfoTypeForString('CIVILIZATION_JAPAN_EUROPE'):
lName = ["Akagi","Akatsuki","Akizuki","Amagiri","Aoba","Argentina","Azuma","Chikuma","Chokai","Furutaka","Haguro","Haruna","Hatsuzakura","Hiei","Hiryu","Hosho","Ikazuchi","Itsukushima","Jintsu","Junyo","Kaga","Kaiyo","Kako","Kikuzuki","Kinai","Kinugasa","Kirishima","Kongo","Kôtetsu","Mikuma","Minegumo","Murasame","Musashi","Mutsuki","Nagatsuki","Nisshin","Ryujo","Shimakaze","Shinano","Shoho","Shokaku","Soryu","Takasago","Tenryu","Yamato","Yasoshima","Yubari","Yukikaze","Yura","Zuikaku","Nisshin Maru"]
elif pCiv == gc.getInfoTypeForString('CIVILIZATION_FRANCE') or pCiv == gc.getInfoTypeForString('CIVILIZATION_FRANCE_EUROPE'):
lName = ["Galathee","Mutine","Emeraude","Sirene","Renomee","Amphitrite","Megere","Topaze","Thetis","Heroine","Comete","Fleur de Lys","Licorne","Sauvage","Hermine","Opale","Minerve","Oiseau","Aigrette","Vestale","Felicite","Alcmene","Infidele","Legere","Sincere","Inconstante","Dedaigneuse","Belle Poule","Amphitrite","Tourterelle","Indiscrete","Pourvoyeuse","Consolante","Nymphe","Andromaque","Astree","Sibylle","Nereide","Fine","Emeraude","Charmante","Junon","Gracieuse","Inconstante","Helene","Concorde","Courageuse","Hermione","Iphigenie","Surveillante","Resolue","Gentille","Amazone","Prudente","Gloire","Bellone","Medee","Magicienne","Precieuse","Vestale","Alceste","Iris","Reunion","Modeste","Topaze","Ceres","Fee","Galathee","Railleuse","Fleur de Lys","Charente Inferieure","Capricieuse","Friponne","Capricieuse","Prudente","Venus","CleopA¢tre","Felicite","Calypso","Fidele","Fortunee","Semillante","Insurgente","Republique Francaise","Francaise","Nationale","Bravoure","Patriote","Fidele","Dedaigneuse","Themis","Heureuse","Chiffonne","Venus","Sarkozy","Merkel","Dryade","Proserpine","Sibylle","Carmagnole","Danae","Meduse","Didon","Nymphe","Thetis","Cybele","Concorde","Minerve","Junon","Imperieuse","Melpomene","Minerve","Valeureuse","Infatigable","Carrere","Muiron","Seine","Revolutionnaire","Spartiate","Indienne","Furieuse","Virginie","Courageuse","Harmonie","Volontaire","Cornelie","Didon","Rhin","Belle Poule","Surveillante","Atalante","Preneuse","Africaine","Armide","Minerve","Penelope","Flore","Amphitrite","Niemen","Saale","Saale","Alcmene","Circe","Antigone","Cleopatre","Magicienne","Gloire","President","Topaze","Venus","Junon","Calypso","Amazone","Consolante","Piemontaise","Italienne","Danae","Bellone","Nereide","Illyrienne","Galatee","Milanaise","Vistule","Oder","Oder","Perle","Hortense","Hermione","Pomone","Manche","Caroline","Pauline","Corona","Pallas","Elbe","Amelie","Clorinde","Renommee","Elisa","Favorita","Astree","Fidele","Adrienne","Aurore","Nymphe","Iphigenie","Meduse","Pregel","Ariane","Medee","Andromaque","Yssel","Carolina","Gloire","Meuse","Terpsichore","Erigone","Arethuse","Melpomene","Rubis","Atalante","Ceres","Piave","Dryade","Dryade","Sultane","Etoile","Rancune","Amphitrite","Cybele","Duchesse de Berry","Constance","Thetis","Astree","Armide","Proserpine","Iphigenie","Nereide","Ceylon","Vengeance","Resistance","Forte","Egyptienne","Romaine","Immortalite","Impatiente","Incorruptible","Revanche","Libre","Comete","Desiree","Poursuivante","Jeanne d'Arc","Clorinde","Amazone","Vestale","Venus","Ceres","Syrene","Atalante","Artemise","Andromede","Gloire","Poursuivante","Virginie","Cleopatre","Danae","Nereide","Zenobie","Alceste","Pandore","Sibylle","Reine Blanche","Surveillante","Iphigenie","Terpsichore","Dryade","Herminie","Melpomene","Didon","Uranie","Belle Poule","Semillante","Andromaque","Forte","Renommee","Perseverante","Vengeance","Entreprenante","Erigone","Africaine","Jeanne d'Arc","Penelope","Chartre","Psyche","Clorinde","Heliopolis","Algerie","Isis","Zuiderzee","Dolfijn","Eenhoorn","Salamander","Gelderland","Fredrik Hendrik","Eendracht","Zon","Groningen","Ter Goes","Prinses Roijael","Utrecht","Gewapende Ruyter","Maan","Zeven Provincien","Haarlem","Brederode","Huis van Nassau","Graaf Willem","Kameel","Vrede","Jaarsveld","Vrijheid","Mercurius","Louisa Hendrika","Vogelstruis","Witte Lam","Groote Liefde","Campen","Sint Matheeus","Rosenkrans","Zeelandia","Vlissingen","Middelburg","Kampveere","Prins Willem","Gelderland","Eendracht","Prinses Amalia","Dordrecht","Sint Matheeus","Caleb","Jupiter","Drie Helden Davids","Willem van Nieuhoff","Westergo","Stad en Lande","Prinses Albertina","Oostergo","Huis te Swieten","Huis te Cruiningen","Delfland","Amsterdam","Landman","Huis te Oosterwijk","Beurs van Amsterdam","Jozua","Duivenvoorde","Doesburg","Carolus Quintus","Zeelandia","Westvriesland","Prinses Maria","Admiraal","Kapitein","Hollandia","Akerboom","Prince Friso","Prins Willem","Kasteel van Medemblik","Koning William","Keurvorst van Brandenburg","Brandenburg","Saksen","Beschermer","Beschermer","Unie","Gouda","Reigersberg","Zeven Provincien","Vrijheid","Zeelandt","te Veere","Nassauw","Middelburg","Eendragt","Matenes","Hardenbroek","Overwinnaer","Buis","Wolfswinkel","Starrenburg","Schonauwen","Huis te Nek","Loosdregt","Boetzelaer","Amsterdam","Ter Meer","Duinveld","de Purmer","Leyden","Gelderland","Roozendaal","Gouda","Souterwoude","Haarlem","Kasteel van Egmont","Polaanen","Damiaten","Tholen","Heemstede","Kasteel van Medenblick","Valkenburg","Beemsterlust","Twikkelo","Maas","Proventie Utrecht","Ramhorst","Prins Friso","Boekenroode","Delft","Brederode","Vrijheid","Moriaanshoofd","Watervlied","Zierikzee","ter Goes","Vlissingen","Assendelft","Haarlem","Delft","London","Helverson","Cambridge","Warspite","Revenge","Defiance","Canterbury","Sunderland","Tilbury","Eagle","Windsor","Chester","Harwich","Winchester","Maidstone","Colchester","Portland","Falkland","Salisbury","Advice","Gloucester","Norwich","Ruby","Colchester","Lichfield","Panther","Bristol","Rochester","Royal George","Britannia","Princess Amelia","Vanguard","Somerset","Orford","Grafton","Swiftsure","Northumberland","Buckingham","St Albans","Anson","Tiger","Weymouth","York","Medway","Assistance","Greenwich","Tavistock","Falmouth","Newcastle","Dartmouth","Severn","Woolwich","Namur","Union","Neptune","Cambridge","Chichester","Dunkirk","Achilles","Dublin","Norfolk","Lenox","Mars","Shrewsbury","Warspite","Resolution","Fame","Hero","Hercules","Thunderer","Bellona","Dragon","Superb","Kent","Defence","Valiant","Triumph","Arrogant","Cornwall","Edgar","Goliath","Zealous","Audacious","Elephant","Bellerophon","Saturn","Vanguard","Excellent","Illustrious","Canada","Majestic","Orion","Captain","Albion","Grafton","Alcide","Fortitude","Irresistible","Ramillies","Monarch","Magnificent","Marlborough","Suffolk","Terrible","Russell","Invincible","Robust","Prince of Wales","Ajax","Royal Oak","Conqueror","Bedford","Hector","Vengeance","Sultan","Egmont","Elizabeth","Resolution","Cumberland","Powerful","Defiance","Swiftsure","Culloden","Thunderer","Venerable","Victorious","Ramillies","Terrible","Hannibal","Theseus","Alfred","Alexander","Warrior","Montagu","Ganges","Culloden","Tremendous","Invincible","Minotaur","Leviathan","Carnatic","Colossus","Minotaur","Asia","Essex","Africa","Exeter","Europa","Trident","Prudent","Ardent","Raisonnable","Agamemnon","Belliqueux","Nassau","Indefatigable","Worcester","Lion","Stirling Castle","Intrepid","Monmouth","Defiance","Nonsuch","Ruby","Vigilant","Eagle","America","Anson","Polyphemus","Magnanime","Sampson","Repulse","Diadem","Standard","Inflexible","Africa","Dictator","Sceptre","Crown","Ardent","Scipio","Panther","Firm","Warwick","Romney","Salisbury","Centurion","Portland","Bristol","Renown","Isis","Leopard","Hannibal","Jupiter","Leander","Adamant","Assistance","Europa","Experiment","Medusa","Grampus","Cato","Trusty","Caledonia","Britannia","Prince Regent","Royal George","Nelson","Saint Vincent","Howe","Saint George","Royal William","Neptune","Waterloo","Trafalgar","Ville de Paris","Hibernia","Ocean","Impregnable","Trafalgar","Princess Charlotte","Royal Adelaide","Dreadnought","Neptune","Temeraire","Union","Rodney","London","Formidable","Monarch","Vengeance","Thunderer","Powerful","Clarence","Foudroyant","Rochfort","Sandwich","Waterloo","Cambridge","Indus","Hindostan","Brunswick","Mars","Centaur","Courageux","Plantagenet","Bulwark","Valiant","Ajax","Kent","Conqueror","Dragon","Northumberland","Renown","Achilles","Colossus","Warspite","Fame","Albion","Hero","Illustrious","Marlborough","York","Hannibal","Sultan","Royal Oak","Aboukir","Bombay","Swiftsure","Victorious","Repulse","Eagle","Sceptre","Magnificent","Valiant","Elizabeth","Cumberland","Venerable","Talavera","Belleisle","Malabar","Blake","Santo Domingo","Armada","Cressy","Vigo","Vengeur","Ajax","Conquistador","Poitiers","Berwick","Egmont","Clarence","Edinburgh","Scarborough","Mulgrave","Anson","Gloucester","Dublin","Vindictive","Blenheim","Cornwall","Pembroke","Indus","Redoubtable","Devonshire","Defence","Hercules","Agincourt","Wellington","Cornwallis","Wellesley","Carnatic","Black Prince","Melville","Hawke","Chatham","Hastings","Augusta","Imaun","Antelope","Diomede","Grampus","Jupiter","Salisbury","Romney","Isis","Brave","Alexandre","Duquesne","Implacable","Mont Blanc","Scipion","Brave","Maida","Marengo","Abercrombie","Genoa","Rivoli","Royal Albert","Windsor Castle","Marlborough","Royal Sovereign","Prince of Wales","Queen","Victoria","Frederick William","Algiers","Royal Sovereign","Albion","Aboukir","Exmouth","Saint Jean D'Acre","Hannibal","Princess Royal","Hannibal","Algiers","Caesar","Vanguard","Goliath","Superb","Meeanee","Collingwood","Centurion","Mars","Lion","Majestic","Colossus","Irresistible","Brunswick","Orion","Hood","Edgar","Sans Pareil","Boscawen","Cumberland","Duke of Wellington","Marlborough","Royal Sovereign","Prince of Wales","Royal Albert","Windsor Castle","Orion","Hood","Edgar","Caesar","Algiers","Princess Royal","Hannibal","Rodney","Nile","London","Nelson","Prince Regent","Royal George","St George","Royal William","Neptune","Waterloo","Trafalgar","Albion","Goliath","Collingwood","Centurion","Mars","Lion","Majestic","Nonpareil","Ajax","Blenheim","Edinburgh","Hogue","Cornwallis","Hastings","Hawke","Pembroke","Russell","Victoria","Howe","St Jean d'Acre","Conqueror","Donegal","Duncan","Gibraltar","Agamemnon","James Watt","Victor Emanuel","Edgar","Hero","Revenge","Renown","Atlas","Anson","Defiance","Bulwark","Robust","Repulse","Zealous","Royal Alfred","Royal Oak","Triumph","Ocean","Caledonia","Blake","Kent","Pitt","Warrior","Black Prince","Defence","Resistance","Hector","Valiant","Minotaur","Agincourt","Northumberland","Prince Consort","Caledonia","Ocean","Lord Clyde","Lord Warden","Captain","Audacious","Invincible","Iron Duke","Vanguard","Swiftsure","Triumph","Devastation","Thunderer","Superb","Agamemnon","Ajax","Scorpion","Wyvern","Cerberus","Magdala","Belleisle","Orion","Conqueror","Nuno Tristao","Diogo Gomes","Diogo Cao","Corte Real","Pero Escobar","Alvares Cabral","Pacheco Pereira","Dom Francisco","Vasco da Gama","Almirante Pereira","Almirante Gago Coutinho","Almirante Magalhaes","Joao Belo","Comandante Roberto Ivens","Hermenegildo","Sacadura Cabral","Vasco da Gama","Alvares Cabral","Corte Real","Bartolomeu Dias","Finska Svan","Svenska Hektor","Christopher","Engel","St Erik","Mars","Enharning","Memnon","Jonas von Emden","Hollands Galej","Kalmar Bark","Rada Drake","Roda Lejon","Finska Memnon","Trekronor","Vasa","Applet","Applet","Applet","Kristina","Jupiter","Mars","Krona Ark","Gata Ark","Scepter","Patentia","Oldenburg","Lejon","Andromeda","Vestervik","Cesar","Maria","Sankt Anna","Wismar","Herkules","Carolus","Merkurius","Falk","Amarant","Apollo","Drake","Mane","Gateborg","Viktoria","Pelikan","Ulven","Fenix","Andromeda","Monikendam","Saturnus","Wrangel","Nyckel","Jupiter","Spes","Mars","Sol","Venus","Krona","Svenska Lejon","Wismar","Merkurius","Neptunus","Hieronymus","Wrangels","Pallats","Kalmar","Hjalmar","Carolus","Ulrika","Gota","Hedvig","Karlskrona","Wrangel","Upland","Hercules","Drottning","Wachtmeister","Prins Carl","Halland","Gotland","Lifland","Estland","Osel","Konung Karl","Princessa Hedvig","Wenden","Viktoria","Pommern","Ulrika Eleanora","Kalmar","Stettin","Goteborg","Frederika Amalia","Norrkoping","Wismar","Warberg","Elfsborg","Gatha Lejon","Nordstjerna","Prins Carl Fredrik","Bremen","Aland","Tre Kroner","Werden","Riga","Stockholm","Prinsessa Fredrika","Halmstad","Prins Carl","Kronskepp","Ulrika Eleonora","Greve Sparre","Sophia Charlotta","Fred","Frihet","Drottningholm","Hessen Cassel","Enighet","Sverige","Prins Wilhelm","Finland","Adolf Fredrik","Sparre","Uppland","Sadermanland","Gotha","Fredrik Rex","Prins Carl","Prins Gustaf","Sophia Albertina","Sofia Magdalena","Fredrik Adolph","Adolph Fredrik","Gustaf","Kronprins Gustaf","Wladislaff","Louisa Ulrika","Konung Gustaf","Prins Oscar","Gustav den Store","Stockholm","Budapest","Monarch","Wien","Kronprinz Rudolf","Kronprinzessin","Maria Theresia","Kaiser Karl VI","Sankt Georg","Venus","Bellona","Novara","Schwarzenberg","Minerva","Diana","Carolina","Pylades","Pola","Montecuccoli","Hussar","Arthemisia","Arethusa","Saida","Dromedar","Bravo","Fido","Camaeleon","Roma","Jupiter","Gorzkowski","Messagiere","Achilles","Taurus","Vulkan","Custoza","Curtatone","Santa Lucia","Volta","Prinz Eugen","Kaiserin Elisabeth","Radetzky","Adria","Donau","Novara","Schwarzenberg","Laudon","Erzherzog Friedrich","Dandolo","Donau","Saida","Donau","Helgoland","Fasana","Zrinyi","Aurora","Frundsberg","Zara","Spalato","Sebenico","Lussin","Panther","Leopard","Tiger","Franz Joseph I","Kaiserin Elisabeth","Aspern","Szigetvar","Zenta","Admiral Spaun","Saida","Helgoland","Novara","Warasinder","Drache","Salamander","Kaiser Max","Prinz Eugen","Ferdinand Max","Habsburg","Lissa","Maros","Leitha","Kaiser","Custozza","Erzherzog Albrecht","Kaiser Max","Prinz Eugen","Tegetthoff"]
elif pCiv == gc.getInfoTypeForString('CIVILIZATION_DUTCH') or pCiv == gc.getInfoTypeForString('CIVILIZATION_RUSSIA_EUROPE'):
lName = ["Apostol Pavel","Prorochestvo","Sviatogo Dukha","Sviatoi Ilya","Shlisselburg","Kronshloty","Peterburg","Putin","Yeltsin","Narva","Mikhail Arkhangel","Ivan-gorod","Olifant","Dumkrat","Sviatoi Piotr","Sviatoi Pavel","Samson","Sviatoi Yakov","Sviatoi Nikolai","Lansdou","Richmond","Sviatoi Ilya","Endracht","Kreyser","Rossiya","Vakhmeister","Mitau","Gektor","Kavalier","Merkurius","Apollon","Yagudiil","Arkhangel Mikhail","Kreyser","Vakhtmeister","Rossiya","Sviatoi Mikhail","Sviatoi Sergii","Gremiaschii","Nadezhda","Afrika","Sviatoi Fiodor","Vestovoi","Nadezhda Blagopoluchiya","Sviatoi Aleksandr","Vtoraya Ekaterina","Pochtalyon","Paros","Pobeda","Sviatoi Nikolai","Sviatoi Pavel","Slava","Konstantsiya","Pomoschnyi","Ungaria","Bohemia","Pavel","Nataliya","Stchastlivyi","Sviatoi Mikhail","Pospeshnyi","Aleksandr","Voin","Mariya","Patrikii","Simion","Nadezhda","Slava","Vozamislav","Podrazhislav","Blagopoluchiya","Gektor","Mstislavets","Yaroslavets","Riga","Premislav","Briachislav","Arkhangel Gavriil","Pomoschnyi","Kronstadt","Arkhipelag","Narva","Revela","Riga","Arkhangel Mikhail","Rafail","Stchastlivyi","Emmanuil","Emprenabla","Pospeshnyi","Tikhvenskaya Bogoroditsa","Feodosii Totemskii","Speshnyi","Argus","Bystryi","Merkurii","Patrikii","Liogkii","Patrikii","Merkurii","Provornyi","Vestovoi","Konstantin","Aleksandra","Mariya","Olga","Kniaginia Lovitch","Elisaveta","Ekaterina","Anna","Prints Oranskii","Neva","Bellona","Yunona","Pomona","Tserera","Kastor","Amfitrida","Prozerpina","Diana","Avrora","Melapomena","Konstantin","Liogkii","Neva","Geroi","Amfitrida","Avtroil","Arkhipelag","Argus","Diana","Avtroil","Liogkiy","Kastor","Poluks","Venera","Sveaborg","Poluks","Rossiya","Neva","Pomona","Pomoschnyi","Provornyi","Pospeshnyi","Gektor","Kreyser","Aleksandr Nevskii","Kastor","Elena","Aleksandr Nevskii","Pallada","Diana","Narva","Borodino","Vilagosh","Sysoi Velikii","Pervyi","Vtoroi","Tretiy","Chetviortyi","Piatyi","Shestoi","Sedamoi","Vosamoi","Deviatyi","Desiatyi","Odinnadtsatyi","Dvenadtsatyi","Trinadtsatyi","Chetyrnadtsatyi","Piatnadtsatyi","Shestnadtsatyii","Vestnik","Grigorii Velikiya Armenii","Sergii Chudotov","Nikolai","Sviatoi Georgii","Taganrog","Kinburn","Berislav","Fanagoriya","Apostol Andrei","Aleksandr Nevskii","Piotr Apostol","Ioann Bogoslov","Tsara Konstantin","Fiodor Stratilat","Kazanskaya","Belomorskii","Matvei","Sviatoi Nikolai","Grigorii Velikiya","Ioann Zlatousty","Stchastlivyi","Liogkii","Mikhail","Nazaret","Krepkii","Voin","Afrika","Minerva","Vezul","Speshnyi","Evstafii","Flora","Pospeshnyi","Shtandart","Rafail","Tenedos","Erivana","Arkhipelag","Varna","Enos","Burgas","Agatopola","Brailov","Flora","Mesemvriya","Sizopola","Midiya","Kagul","Kovarna","Kulevtchi","Kavkaz","Astrakhana","Kizliar","Tsaritsyn","Provornyi","Ekaterina","Aleksandr","Aleksandra","Elena","Konstantin","Mariya","Nikolai","Pavel","Aleksandr","Ekaterina","Elizaveta","Mariya","Konstantin","Nikolai","Bogoyavleniye","Emmanuil","Vifleem","Peterhof","Bodryi","Neva","Sveborg","Torneo","Mirnyi","Nadezhda","Malyi","Uraniya","Rossiya","Nadezhda","Otvazhnosta","Postoyanstvo","Vernosta","Uspekh","Nadezhda","Karlskron-Vapen","Venker","Dansk-Ern","Kisken","Star Feniks","Brilyant","Ulriksdal","Arkhipelag","Naktsiya","Minerva","Avtroil","Oden","Gelgomar"]
if pCiv == gc.getInfoTypeForString('CIVILIZATION_SPAIN') or pCiv == gc.getInfoTypeForString('CIVILIZATION_SPAIN_EUROPE'):
sFull = "USS "+lName[CyGame().getSorenRandNum(len(lName), "Name Gen")-1]
else:
sFull = lName[CyGame().getSorenRandNum(len(lName), "Name Gen")-1]
# trim name length
if len(sFull) > 25:
sFull = sFull[:25]
return sFull
#end shipname modcomp
 
... but I think RaR brought shipnames directly into civilizationinfos.xml.

Yes, I implemented the logic for that feature already for TAC.
(The lists of ships were supplied by other team members.)

So it also became part of RaR.

I prefer to do such things in DLL and XML.
 
Wow, that was faster than a Corvette with Fusion Cores & the Blockade Runner profession! :cool::scan:
All of a sudden what remained turned out to be fixable in no time. However I added #ifdefs in CvCity::doYields() and I plan to go back to do it better. For instance right now the code to disable yet to be invented yields works on a hardcoded list of yields. I want to make a new yield group to give modding access to invent yields. It has a few issues like that, but nothing which should prevent modding at the stage it is in right now.

However when trying to clean or build I get the following error:
[nmake error]
Either you didn't install nmake or windows in unable to find nmake.exe. There could be two reasons for that.

1: You didn't install nmake. The VC++ 10 installer should have included it and I assume you got it.

2: your PATH system environment variable is set incorrectly.
Guide to change it: http://www.computerhope.com/issues/ch000549.htm
Windows will check all directories in PATH when given a filename. Looks like there aren't any nmake.exe there.
The string to add to PATH (at least in my case) is
Code:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin
You should be aware that each path in PATH is separated by a semicolon (;). You should add that as well to ensure you don't mix it with other paths.

EDIT: alternatively if you don't want to mess with system environment variables, then I think it would work if you copy nmake.exe from that directory into DLL_sources. At least it's worth a try. I can't test it because I don't want to remove the path from my PATH even if it's just for testing this.

I say that having to add the path to PATH manually is a bug in the VC++ installer. It's needed for full functionality and it failed to do it for me as well.

But when trying to Build the solution get the following boost and python error.
As I'm (was) unaware of the steam install path I couldn't provide it to the Makefile. I will do so. However until I have done that, you can add this to Makefile.settings
Code:
CIV4_PATH=c:\Program Files (x86)\Steam\steamapps\common\civilization iv colonization\CvGameCoreDLL
Alternatively you can copy the boost and python directories from CvGameCoreDLL into DLL_sources. I prefer just linking to the one Colonization provided as it's like 50-60 MB. It adds up if you have a copy for each source code.
Also Firaxis never updated those two libraries meaning you can take the ones from civ4 warlords or bts if you like. They are interchangeable as they are identical.

I prefer to do such things in DLL and XML.
I fully agree on that one. All setup should be done in XML if possible and coding should be in DLL. Python is annoying to fix bugs in and is much slower than C++ and as such should be avoided if possible. However the API in the DLL makes it fairly easy to make screen setup in python.


Important!
When setting the source to compile for 2071, do select the DLL in Assets and set git to ignore it. We don't want an accidental 2071 DLL file commit into M:C ;)
Also whenever Makefile.settings changes CUSTOM_CFLAGS, clean all targets. I would recommend not shifting back and forth, but there might be a need at some point and then it's important to remember.
The fastest way to clean all targets is to delete the directory temp_files. You can set this directory to a different name/location with TEMP_FILE_DIR in Makefile.settings, but there really is little need for it, unless special cases like you compile from a network drive or another slow drive as file access speed is important for compiletime.
 
great, I did as you recommended and the clean and build went perfectly! :cool::goodjob:

To test things out I loaded the new DLL with the XML framework from the 2071 github branch which was cleaned from M:C specific XML tags. On loading I again got those asserts from GameInfo/CIV4ForceControlInfos.xml , which are odd given that M:C doesn't change that file and the vanilla vesion doesn't refer to the M:C specific tags in the assert. I'm assuming some remnant of hardcoding in the DLL is what's causing them but not sure why the asserts mention GameInfo/CIV4ForceControlInfos.xml .

Spoiler :
Assert Failed

File: CvGlobals.cpp
Line: 3119
Expression: strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type YIELD_CLOTH not found, Current XML file is: xml\GameInfo/CIV4ForceControlInfos.xml

Assert Failed

File: CvGlobals.cpp
Line: 3119
Expression: strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type YIELD_SCALE_ARMOR not found, Current XML file is: xml\GameInfo/CIV4ForceControlInfos.xml

----------------------------------------------------------
Assert Failed

File: CvGlobals.cpp
Line: 3119
Expression: strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type YIELD_SILVER not found, Current XML file is: xml\GameInfo/CIV4ForceControlInfos.xml

----------------------------------------------------------
Assert Failed

File: CvGlobals.cpp
Line: 3119
Expression: strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type FUEDALISM not found, Current XML file is: xml\GameInfo/CIV4ForceControlInfos.xml

----------------------------------------------------------
Also got one assert from GameInfo/CIV4HurryInfo.xml , this one makes sense since the vanilla xml does contain YIELD_LUMBER. It'd be no problem to make a 2071-specific CIV4HurryInfo.xml , but it may simplify things just as well to stick with using standard XML tagnames for ultra-common stuff like YIELD_FOOD and YIELD_LUMBER in the 2071 final version.
Spoiler :
Assert Failed

File: CvGlobals.cpp
Line: 3119
Expression: strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type YIELD_LUMBER not found, Current XML file is: xml\GameInfo/CIV4HurryInfo.xml
Also got a couple asserts for YIELD_FOOD and YIELD_LUMBER in buildinginfos, those were my fault for having left a few M:C specific tags in that XML; I've edited it now to remove those & synced a new commit to the 2071 branch.

Thanks again for all your help - :king::goodjob: you've been even more helpful than those aliens who made primates sentient with their handy black monolith! :p:scan:;)
 
Those are some odd asserts. I will take a look later.

I take back the previously announced "must be invented" yield group. I came up with a different idea. I noticed that whenever a possible to invent yield is checked to see if it is invented, the code loops though all civics. Also there is no function to do this meaning more or less the same code is used multiple times. I made a function, which returns true if the player has invented something, which allows the yield or if no inventions allows the yield (available from the start, like food and lumber). It returns false if it can be invented, but the player has no inventions, which provides it.

This function is as slow as the code it is designed to replace. However I designed it to allow caching the output. Each player now stores an on/off for each yield, which can be looked up much faster and there is no need to tell the game which yields can be invented. It is generated automatically by inventions in XML. No risk of getting out of sync.

I have the function and the cache update code and it's updated correctly (hopefully). However now that I'm so far with this, I want to finish it before looking at the asserts. The code never use the function to read the cache, which makes it kind of pointless at the moment ;)


There is likely an XML design change in yields soon. In the M:C bugs thread I proposed moving all variables, which can be on/off from yields into storing the same info as yield groups. It should equally easy to set up and it will run faster. Kailric seems to like that idea.
It's unlikely that we will make groups for other XML files like this. We do it with yields because those are called all the time and speed is an issue. Other XML files are less critical.


The youtube link can appear in the forum. All you have to write is
Code:
[plain][CENTER][YOUTUBE]Y15NnGZIBuM[/YOUTUBE][/CENTER][/plain]

It will then appear like this:


Naturally you can omit the center part if you want the video to be displayed on the left.
 
Those are some odd asserts. I will take a look later.
CIV4ForceControlInfos.xml asserts usually means that one of the GlobalAltDefines is missing or wrong or there is a discrepancy in the CvXMLLoadUtillitySet.cpp file.


I take back the previously announced "must be invented" yield group. I came up with a different idea. I noticed that whenever a possible to invent yield is checked to see if it is invented, the code loops though all civics. Also there is no function to do this meaning more or less the same code is used multiple times. I made a function, which returns true if the player has invented something, which allows the yield or if no inventions allows the yield (available from the start, like food and lumber). It returns false if it can be invented, but the player has no inventions, which provides it.

This function is as slow as the code it is designed to replace. However I designed it to allow caching the output. Each player now stores an on/off for each yield, which can be looked up much faster and there is no need to tell the game which yields can be invented. It is generated automatically by inventions in XML. No risk of getting out of sync.

Nice, that was something I was wanting to do and should have done that from the start. Remember though that some Inventions can disallow Yields, Units, or Professions, etc. Like in the current M:C the invention of the Longbow disallows Archers. In other words the Longbow takes the place of Archers. Also the Censures disallows things. Anyway, just make sure that if the invention reads <iChange>-1</iChange> that it knows this means the object is no longer allowed.

@"Apes see a tall slab"
Best video ever!! :eek: I love that one ape who keeps touching it.
 
Nice, that was something I was wanting to do and should have done that from the start. Remember though that some Inventions can disallow Yields, Units, or Professions, etc. Like in the current M:C the invention of the Longbow disallows Archers. In other words the Longbow takes the place of Archers. Also the Censures disallows things. Anyway, just make sure that if the invention reads <iChange>-1</iChange> that it knows this means the object is no longer allowed.
You are making this complicated :p

Right now I'm only doing this for yields and was tempted to ignore disallowed a yield based on inventions. However I needed to come up with a solution anyway because then adding functions for professions and units should be copy paste+minor changes. Also XML should be allowed to make an invention, which replaces one yield with another, if that is what the modder wants. Sure it's annoying to have your 2000 flint axes taken away just because somebody came up with the idea to use bronze, but that's life :p (ok it's not. Bronze never replaced flint as bronze is actually a tradeoff, not just a bonus).

I came up with this solution instead.
Always loop all yields (that is slower than the current code, but it's only for cache building, so it's ok).
Calculate the max possible value and the current one for the player.
If max is 0 afterwards, then increment the current value.
The yield can be used if current value is greater than zero.

In a more human language it will result in:
Allowing all yields, which can't be invented, unless an invention owned by the player removes them.
Allowing yields once they are invented.
Disallowing yields if they are invented by one invention and then disallowed by another one.

I also allow all yields in YieldGroup_AI_Native_Product if the player is native, disregarding if they are invented or not. I don't know if that is a good idea or not. Maybe we should give the inventions to the natives in M:C like it's done in 2071. That way we solve the same issue for professions and stuff at the same time. We could then prevent natives from trading the inventions if we want. There are a few options, but right now I just hardcoded natives to allow those yields as it will provide a still playable result and it's the fastest solution to code.

The reason why it should be true both if the yield is invented or if it is available from the start is because it allows code like
Code:
if (kPlayer.canUseYield(YIELD_FROM_ANIMALS))
{
    // some hunting code
That way the hunting code is active once luxury food is invented. At the same time it allows 2071 to set YIELD_FROM_ANIMALS to YIELD_NUTRIENTS if it wants to and then hunting is available from the start. The DLL doesn't care if the yield was invented at the start. What it cares about is just if it is available right now. The whole issue of what can be invented is then moved to XML with absolutely no references to it in C++. Checking the cache is rather fast and as such it doesn't really hurt to check even yields, which are available from the start. This gives greater freedom to XML editing than M:C provides right now as the DLL has hardcoded which yields can be invented.
 
yeah that does sound complicated :crazyeye: I hadn't thought of disallowing a yield based on inventions, but its nice to have if its already being implemented similarly for professions. what happens if you capture a city storing yields you haven't invented, or you get some via goodyhut or event?
That way the hunting code is active once luxury food is invented. At the same time it allows 2071 to set YIELD_FROM_ANIMALS to YIELD_NUTRIENTS if it wants to and then hunting is available from the start. The DLL doesn't care if the yield was invented at the start. What it cares about is just if it is available right now. The whole issue of what can be invented is then moved to XML with absolutely no references to it in C++. Checking the cache is rather fast and as such it doesn't really hurt to check even yields, which are available from the start. This gives greater freedom to XML editing than M:C provides right now as the DLL has hardcoded which yields can be invented.
For hunting, could it be feasible to instead of using one YIELD_FROM_ANIMALS in DLL, add a moddable <YieldsonKill> tag in unitinfos? That way any particular beastie could have an appropriate type of yield and larger/tougher ones could have a larger amount. That could also be used to get some salvage or loot from defeating certain military enemies or ships (it looks like even medieval knights got a decent chunk of their income from some judicious battlefield looting:king:)

I'm scanning wikipedia for content ideas, there is some cool stuff in here!
http://en.wikipedia.org/wiki/List_of_emerging_technologies
For instance, who knew that much of the Moon is composed of a substance known as KREEP rich in radioactive thorium and rare earths :eek: (Don't worry I'm not planning to implement a YIELD_KREEP, just thought it was cool lol. Woulda been perfect for Moonraker.)

I'm trying to balance things as best as possible through the design doc; with the goal of getting each yield, specialist and profession to be reasonably balanced with each other, while not being boring in all having identical gameplay effects. Right now there are 5 main resource-harvesting unitclasses, each of which can gain the ability to harvest a cluster of 3 yield types that would have slightly increasing value/rarity from top to bottom; plus a fourth "special" yield that one of the other specialists can also harvest for versatility. If the design itself is somewhat systematic I'm hoping it may be possible to add terrains and techs using similar simple "rules", avoiding finding out later that things are totally unbalanced or unfun for players.

@"Apes see a tall slab"
Best video ever!! I love that one ape who keeps touching it.
yeah my sister's cat is like that with its scratching post.. only a matter of time till it becomes hyperintelligent :evil::p about that earlier scifi post, I'd guess Kubrick's 2001 turned out to be one of the least off-the-wall as far as future predictions (besides taking a Pan Am space plane to visit moon bases! ;)) I'd say Siri is at least as psychotic as HAL 9000:scan::scan::p
 
yeah that does sound complicated :crazyeye: I hadn't thought of disallowing a yield based on inventions. what happens if you capture a city storing yields you haven't invented, or you get some via goodyhut or event?
doYields() will remove those yields. This function is called whenever you hit end turn meaning you will lose everything stored within max one turn.

I don't think it would be a good idea to remove yields like that, but the DLL will allow it. This is partly to make the yield checking code similar to profession and unit checking code. As Kailric said it does make sense to be able to make an invention, which disallows one profession and enables another. I don't know what happens to units already using that profession, but that's not my concern right now. My main goal with this change is actually to get rid of the hardcoded list in doYields() of yields, which might not be invented yet. At first I planned for a yield group for this, but looking at the code I realized that this is a much better solution. It's a lot faster and self configuring and presumably we don't have to touch it again once it's done.

For hunting, could it be feasible to instead of one YIELD_FROM_ANIMALS, add a <YieldsonKill> tag in unitinfos? That way any particular beastie could have an appropriate type of yield and larger/tougher ones could have a larger amount. That could also be used to get some salvage or loot from defeating certain military enemies or ships (it looks like even medieval knights got a decent chunk of their income from some judicious battlefield looting:king:)
Most likely. However I'm not going to change that feature that much right now. All I'm doing is getting rid of hardcoded yields. Adding new features like that is somewhat out of that scope and it will have to wait.
 
I don't know what happens to units already using that profession, but that's not my concern right now.

If I recall correctly I had lots of issues with this. If a unit has a profession that isn't allowed it causes all sorts of issues. I do believe that I made it so all those professions auto convert to the new profession. I'd have to look through the code again to know for sure. If your realm gets Censured from Priest profession then all your current Priest get ejected from the city, I know that much:)
 
Kailric :spank:
I found a loop, which loops all inventions in CvPlot::calculateNatureYield(). This function is called for every worked plot and every city plot at the start of every turn. In other words this is an important function when it comes to performance. Luckily the loop is inside code, which is only executed by human players. However that leaves a different question: why is the AI allowed to produce yields they haven't invented yet?

Maybe it would be a good idea to make the AI suffer from uninvented yields once the performance issue is solved. Remember that natives can use all yields set in YieldGroup_AI_Native_Product even if they lack the proper invention to enable those.

I can't even get rid of the loop without caching getAllowsBonuses() and getCenterPlotFoodBonus() as well. However they will be cached too. Their presence in this time critical function alone justifies the time to write a cache for all of them.

Firaxis :spank:
I noticed that when you use GET_PLAYER() you get a copy of the player. This mean when I want to get one variable from a player, it copies the entire player and then it provides that one variable from the copy. Afterwards the copy goes out of scope and the memory is freed. The player class is rather big and it would be faster to just return a pointer to the original.

The copy/pointer issue is far more severe than that. Given that it provides a copy, we can write data in the copy without affecting the original. The reason why it still works is if you read a pointer from the copy, it will point to the same location as the original and so far we only change data given with pointers from CvPlayer... or at least it looks like it. There might be hidden bugs in this.

I decided to allocate an array directly in the class and this will not work. I think I will change it to a just-in-time array because that one is based on a pointer to an array and it will fix that problem. However it's a bit slower.

I feel like rewriting GET_PLAYER() to return a pointer, but that would likely be a big task. Also I think other big classes suffer from the same issue. Some people avoids pointers at all cost because they appear to be harder to understand. However I expected Firaxis to be better than that. Makes me wonder how ugly code we use from other companies where we just can't see the code.

Looks like I could be busy for a while cleaning up code written by other people. We will love it once it's done though.
 
I noticed that when you use GET_PLAYER() you get a copy of the player.
...
Given that it provides a copy, we can write data in the copy without affecting the original.

:confused:

I can't believe that is true.

Half of my features are using GET_PLAYER() and then changing / storing data at that Player by calling some set() or increase() or ... method.
They would all not work then, but they do.

This is the absolutley most used method in the whole DLL.
If it was flawed, than at least some of the DLL-modders (Civ4BTS or Civ4Col) would have noticed years ago.
 
did you notice based on its expression, that pac-man being spanked seems to be enjoying it a bit much :eek::crazyeye: lol, what kind of emoticons is civfanatics implementing these days? :lol:
Originally Posted by Nightinggale
I found a loop, which loops all inventions in CvPlot::calculateNatureYield(). This function is called for every worked plot and every city plot at the start of every turn. In other words this is an important function when it comes to performance. Luckily the loop is inside code, which is only executed by human players. However that leaves a different question: why is the AI allowed to produce yields they haven't invented yet?

Maybe it would be a good idea to make the AI suffer from uninvented yields once the performance issue is solved. Remember that natives can use all yields set in YieldGroup_AI_Native_Product even if they lack the proper invention to enable those.
One yields-related problem I remember facing with the old version of 2071 was, the game didn't seem to update tile yields appropriately once a Bonus is discovered via tech, or even via <iDiscoverRnd> in improvementinfos.xml , which is a vanilla game feature. However, the techs that gave a boost to tile yield production from a given Bonus or Improvement seemed to work well as far as I could tell. It would be computationally expensive to recalculate yields for every tile on the map frequently as you say, but hopefully this might only need to be done for all tiles owned by that player when a tech or FF is discovered, and locally to recalculate yield for a given tile if its ownership changes.

Kailric wrote:
Nice, that was something I was wanting to do and should have done that from the start. Remember though that some Inventions can disallow Yields, Units, or Professions, etc. Like in the current M:C the invention of the Longbow disallows Archers. In other words the Longbow takes the place of Archers. Also the Censures disallows things. Anyway, just make sure that if the invention reads <iChange>-1</iChange> that it knows this means the object is no longer allowed.
As complex as it may be to work out all the coding issues involved, I think this is a great feature for modmodding. It'll allow things like advanced social techs obsoleting inferior starting unittypes such as Serf or Convict. You could also use techs to upgrade a basic starting Profession that produces one yieldtype to one that produces two. (e.g. in M:C could start with Fur Trapper producing YIELD_FUR , then later replace that profession with Game Warden that produces YIELD_FUR and YIELD_FOOD from Fur-containing tiles. :king:

The Censures also are cool, I like that they are effectively Civics/Techs themselves making them very customizable. How is it that the King/Pope decides when/if to issue certain Censure types? Maybe the 2071 tyrants could issue edicts like Media Censorship or Narcotics Crackdown with various oppressive effects. :scan::cool:
 
As complex as it may be to work out all the coding issues involved, I think this is a great feature for modmodding.

It is often a far way however from a great idea to a great implementation.
(Stability, Balancing and Performance.)

When I was thinking about implementing an "inventions" system of my own, I cancelled many ideas again,
because I realized that I could not implement them in a really performant way.

The coolest feature will not help you, if it will ruin performance of your mod.

I never understood why many modders totally ignored performance aspects when implementing features in DLL. :dunno:
Thus it is really great, that Nightinggale pays attention to that aspect. :thumbsup:
 
Thus it is really great, that Nightinggale pays attention to that aspect.
Well, it certainly is. I can already tell that despite all the new and detailed game features it adds M:C itself is running noticeably faster/smoother than the Firaxis original. I would never have had a clue about all the original coding issues that existed with C4C.
 
:confused:

I can't believe that is true.

Half of my features are using GET_PLAYER() and then changing / storing data at that Player by calling some set() or increase() or ... method.
They would all not work then, but they do.

This is the absolutley most used method in the whole DLL.
If it was flawed, than at least some of the DLL-modders (Civ4BTS or Civ4Col) would have noticed years ago.
I agree and I have seen code, which surprises me a bit that it works. It looks a bit like some strange hybrid syntax. It appears to work, but then you write GET_PLAYER().function(). If it were a "normal" pointer, it would be GET_PLAYER()->function(). Maybe it would be best to just ignore this and pray that it keeps on working without the technical explanation for why precisely it works. On the other hand I hate the concept of code I can't understand.

One yields-related problem I remember facing with the old version of 2071 was, the game didn't seem to update tile yields appropriately once a Bonus is discovered via tech, or even via <iDiscoverRnd> in improvementinfos.xml , which is a vanilla game feature. However, the techs that gave a boost to tile yield production from a given Bonus or Improvement seemed to work well as far as I could tell. It would be computationally expensive to recalculate yields for every tile on the map frequently as you say, but hopefully this might only need to be done for all tiles owned by that player when a tech or FF is discovered, and locally to recalculate yield for a given tile if its ownership changes.
We have to do the calculations that often as we have no cache or any other way to tell if the plot changed. However we should make the calculations as fast as possible, like if (city plot) {add precalculated int city plot bonus}. The precalculation can take place whenever the player gets a new civic (invention) or on start/load.

EDIT: I said it wrong for how often the function is said. The correct number is (number of worked plots + number of city plots)*number of yield types. That makes it even worse.

As for the bug. We will look into that if it reappears in 2.0.

As complex as it may be to work out all the coding issues involved, I think this is a great feature for modmodding. It'll allow things like advanced social techs obsoleting inferior starting unittypes such as Serf or Convict. You could also use techs to upgrade a basic starting Profession that produces one yieldtype to one that produces two. (e.g. in M:C could start with Fur Trapper producing YIELD_FUR , then later replace that profession with Game Warden that produces YIELD_FUR and YIELD_FOOD from Fur-containing tiles. :king:
Disallowing a unit or profession shouldn't be a problem. Converting the units from the old to the new is. We could ban new convicts from arriving, but we would still be stuck with the ones already created. The latter needs some serious work to get to work.

The coolest feature will not help you, if it will ruin performance of your mod.
This is basically what got me started with the whole Colonization 2071 mod acceptance coding. It's unbearably slow. Specially now when I'm used to RaR/M:C performance.

I never understood why many modders totally ignored performance aspects when implementing features in DLL. :dunno:
I think the modders generally code as good as they can. I think modders, who ignores performance is because they don't know better. Getting code to work is one thing, another is to figure out how well it will perform. Getting good performance is much harder than just getting a feature to work at any speed.
While I would have preferred great performance from all coders, I say it's better to code slow than to not code at all. If nobody coded unless they were good enough to beat vanilla at performance, then we would have one or two mods, which would be way closer to vanilla than the mods are today.

Thus it is really great, that Nightinggale pays attention to that aspect. :thumbsup:
I optimize to a level where I'm no longer annoyed with waiting times. It's not like it must beat some speed record. I most likely wouldn't have cached how inventions affects yields if it wasn't because I was looking for a way to get rid of hardcoded yields and had to make a change anyway. Going back to the speech I linked to earlier "what if every time we touched the code, we made it better?". Whenever I touch a piece of code anyway I consider the performance in it :)
I did analyze the performance and there is no big hotspots of slow code left in the code. Hunting for code to rewrite purely for better performance is pretty hard and I will no longer do that.

There is one really interesting thing about performance. Almost 20 years ago I started playing the original civ on a 16 MHz CPU and the game ran from a 40 MB HD. The game was very responsive and generally performed sort of like M:C does right now after I added caches. The hardware demands from software has increased faster than the hardware performance. One of the worst thing that happened in computer history is the concept that modern computers are fast enough to handle poor and inefficient code. I think it happened around the same time as another disaster appeared: java.

Well, it certainly is. I can already tell that despite all the new and detailed game features it adds M:C itself is running noticeably faster/smoother than the Firaxis original. I would never have had a clue about all the original coding issues that existed with C4C.
You should be aware if you use an Assert or Release DLL. Using Assert instead of Release slows the game around 30%. We made the decision to have Assert DLLs on git for M:C because it makes bug reports so much better. This mean M:C might be even faster than you think as you compare it with a Release vanilla.
 
Disallowing a unit or profession shouldn't be a problem. Converting the units from the old to the new is. We could ban new convicts from arriving, but we would still be stuck with the ones already created. The latter needs some serious work to get to work.
Actually, IIRC Kailric has already allowed for this as an option through <ConvertsUnitsFrom/> and <ConvertsUnitsTo/> in civicinfos; that way it can be possible to mod either a unit conversion or a ban from new arrivals. Very modular and very nice :king: But in contast to unitclasses where it's no problem leaving old ones around, Kailric mentioned that units apparently can't be left with a disallowed profession without causing problems, so on discovering such a tech it would need to iterate through the player's units once and reset their profession to default (which I think it already does though I'm not sure.)

There is one really interesting thing about performance. Almost 20 years ago I started playing the original civ on a 16 MHz CPU and the game ran from a 40 MB HD. The game was very responsive and generally performed sort of like M:C does right now after I added caches. The hardware demands from software has increased faster than the hardware performance.
Ah those were the days :p In one of my first schools as a child they had an ancient Commodore PET gathering dust in the back. It had a cassette tape drive, where you had to physically press Play and then type >LOAD DUNGEON or whatever.

Come to think of it, it booted almost 20 times faster than Windows 8 :crazyeye::lol:
 
Back
Top Bottom