1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Some modding questions

Discussion in 'Rhye's and Fall Modmods' started by Leoreth, Mar 27, 2010.

  1. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Sorry for the generic title, but I actually got a heap of different questions on modding RFC. I'm quite experienced in changing the XML files now, but everything concerning Python or C++ are rather a mystery to me (less because of the languages' syntax, but because of lack of knowledge where Rhye implemented his features).

    1. Civics
    I decided to completely redo the civics, mainly to allow more realistic combinations and to have common RL civic combinations correspond to viable ingame strategy ("western" capitalist democracies for cottage economy, socialism/communism for specialist economy, fascism for wars). Most features of the original civics stayed the same and have only been moved around a bit.
    My question is:
    First: where did Rhye code his extra features for certain civics (instability from transition to democracy / out of communism and great depressions for free market). They don't seem to be tied to the XML tags, but rather to the position of the civic in the civics screen. I'd like to change that so the effects occur with the right civics again.
    Second: The same for civic related stability. It's difficult to see just from the civilopedia, but I fear that this isn't working correctly either.
    Third: Is it possible to somehow increase the food or hammer yield for certain specialists? Unlike for wonders, XML seems to offer no possibility do this.
    Fourth: Is it possible to forbid certain buildings for a certain civic? I'd like to implement a religious civic that represents "pagan" polytheistic beliefs like the Greek pantheon and has no state religion and cannot build religious buildings, but instead gets +2 happiness from Monuments (which I have renamed Pagan Temples).

    2. Dynamic names
    Same question again, where can I find the algorithm that makes them? I guess my new civics will cause some inconsistencies there, and I also want to make some other changes there.

    3. Replacing civilizations
    I know those questions can get annoying, but I also want to get the holy grail of a new civilization. ;)

    I plan to replace Germany with the HRE to represent "medieval" Germany (easy with just some XML) and to have Prussia spawn in 1700AD to represent "modern" Germany (difficult :mischief:).
    I'd also like to make Byzantium take Celtia's slot in both scenarios and be playable (the Celtic cities will spawn as Natives, which works just as well).

    I am aware of the fact that I can't add a completely new civ and will have to replace another one for them. I'd like this civ to be the Maya, since I consider them to be most disposable. Will problems arise from Prussia taking their slot (first simply because of the order the civs are listed)?

    Of course, I'd also have to tweak the Mayan/Prussian research/happiness/production whatnot penalties ... where can I access them?

    Stability/settler/war maps are another problem. To save me some trouble, I thought I could give Byzantium the same maps as Rome and Prussia the same maps as Germany/HRE. Is that possible, and if so, how?

    UPs and UHVs are a thing of the future, but Prussia should inherit HRE's goals and power. Where can I access them?

    In short: where can I access EVERYTHING? :p

    I know that my plans are ambitious, but hey, you first have to fail before you see what's possible ;) So I'll be thankful even for an answer to just a single of my questions :)

    Thanks in advance.
     
  2. The Number Pi

    The Number Pi Irrational Number

    Joined:
    Jan 29, 2010
    Messages:
    332
    Location:
    Between 3 and 4
    These things are located in the python file Stability.py.
    More specifically:

    Spoiler :
    Code:
    iTempCivicThreshold = iNewBaseStability
                            if (iCivic0 == 3 and iCivic1 == 9): #police and free speech
                                    iNewBaseStability -= 10
                                    #print("iNewBaseStability civic combination1",iNewBaseStability, iPlayer)
                            
                            if (iCivic4 == 22 and iCivic2 == 14): #theo and emanc
                                    iNewBaseStability -= 3
                                    #print("iNewBaseStability civic combination2",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 4 and iCivic1 == 5): #univ and barbar
                                    iNewBaseStability -= 3
                                    #print("iNewBaseStability civic combination3",iNewBaseStability, iPlayer)
                            
                            if (iCivic2 == 13 and iCivic3 == 18): #caste and state prop
                                    iNewBaseStability -= 7
                                    #print("iNewBaseStability civic combination4",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 0 and iCivic1 == 7): #despo and bureo
                                    iNewBaseStability -= 2
                                    #print("iNewBaseStability civic combination5",iNewBaseStability, iPlayer)
                                       
                            if (iCivic1 == 6 and iCivic3 == 18): #vassal and state prop
                                    iNewBaseStability -= 7
                                    #print("iNewBaseStability civic combination6",iNewBaseStability, iPlayer)
    
                            if (iCivic1 == 8 and iCivic4 == 23): #nation and pacifism
                                    iNewBaseStability -= 10
                                    #print("iNewBaseStability civic combination7",iNewBaseStability, iPlayer)
                                    
                            if (iCivic0 == 3 and iCivic1 == 8): #police and nation
                                    iNewBaseStability += 10
                                    #print("iNewBaseStability civic combination8",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 3 and iCivic3 == 18): #police and state prop
                                    iNewBaseStability += 5
                                    #print("iNewBaseStability civic combination9",iNewBaseStability, iPlayer)
    
                            if (iCivic1 == 8 and iCivic3 == 16): #nation and mercant
                                    iNewBaseStability += 6
                                    #print("iNewBaseStability civic combination10",iNewBaseStability, iPlayer)
                                    
                            if (iCivic0 == 1 and iCivic1 == 6): #heredit and vassal
                                    iNewBaseStability += 3
                                    #print("iNewBaseStability civic combination11",iNewBaseStability, iPlayer)
                                    
                            if (iCivic0 == 2 and iCivic1 == 7): #repres and bureo
                                    iNewBaseStability += 4
                                    #print("iNewBaseStability civic combination12",iNewBaseStability, iPlayer)
    
                            if (iCivic2 == 14 and iCivic4 == 24): #emancip and free rel
                                    iNewBaseStability += 2
                                    #print("iNewBaseStability civic combination13",iNewBaseStability, iPlayer)
    
                            if (iCivic1 == 6): #vassallage
                                    if (pPlayer.getCurrentEra() == 2):
                                            iNewBaseStability += 3
                                    else:
                                            iNewBaseStability -= 3
                                    #print("iNewBaseStability civic single 1",iNewBaseStability, iPlayer)
    
                            if (iCivic1 == 7): #burocr
                                    if (pPlayer.getNumCities() <= 5):
                                            iNewBaseStability += 5
                                    else:
                                            iNewBaseStability += max(-7,(5 - pPlayer.getNumCities()))
                                    #print("iNewBaseStability civic single 2",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 2): #represent
                                    iNewBaseStability += max(-7,2*(3 - pPlayer.getNumCities()))
                                    #print("iNewBaseStability civic single 3",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 3): #police
                                    iNewBaseStability += min(10, pPlayer.getNumCities()/5) #slightly counterbalances the effect of number of cities (below)
    
                                    #print("iNewBaseStability civic single 4",iNewBaseStability, iPlayer)
                                    
                            if (iCivic1 == 8): #nationhood
                                    iNewBaseStability += 3*teamPlayer.getAtWarCount(True)
                                    #print("iNewBaseStability civic single 5",iNewBaseStability, iPlayer)
    
                            if (iCivic0 == 0): #despotism
                                    if (self.getStability(iPlayer) < -60):
                                            self.setStability(iPlayer, self.getStability(iPlayer)+20)
                                            #print("iNewBaseStability civic first column 1",iNewBaseStability, iPlayer)
                            if (iCivic0 == 1): #hereditary rule
                                    if (self.getStability(iPlayer) < -50):
                                            self.setStability(iPlayer, -50)
                                            #print("iNewBaseStability civic first column 2",iNewBaseStability, iPlayer)
                            if (iCivic0 == 2): #representation
                                    if (self.getStability(iPlayer) > 30):
                                            iNewBaseStability += 5
                                            #print("iNewBaseStability civic first column 3",iNewBaseStability, iPlayer)
                            if (iCivic0 == 3): #police state
                                    if (self.getStability(iPlayer) < -60):
                                            self.setStability(iPlayer, self.getStability(iPlayer)+30)
                                            #print("iNewBaseStability civic first column 4",iNewBaseStability, iPlayer)
                            if (iCivic0 == 4): #universal suffrage
                                    if (self.getStability(iPlayer) > 50):
                                            iNewBaseStability += 10
                                            #print("iNewBaseStability civic first column 5",iNewBaseStability, iPlayer)
                                            
                            if (teamPlayer.isHasTech(con.iDemocracy)):
                                    if (iCivic0 != 4): #universal suffrage
                                            iNewBaseStability -= 3
                                            #print("iNewBaseStability universal suffrage",iNewBaseStability, iPlayer)
                                    if (iCivic2 != 14): #emancipation
                                            iNewBaseStability -= 3
                                            #print("iNewBaseStability emancipation",iNewBaseStability, iPlayer)
                            if (teamPlayer.isHasTech(con.iLiberalism)):
                                    if (iCivic1 != 9): #free speech
                                            iNewBaseStability -= 3
                                            #print("iNewBaseStability free speech",iNewBaseStability, iPlayer)
    
                            if (teamPlayer.isHasTech(con.iBronzeWorking) and not teamPlayer.isHasTech(con.iConstitution)):
                                    if (iCivic2 == 11): #slavery
                                            iNewBaseStability += 3
                                            #print("iNewBaseStability slavery",iNewBaseStability, iPlayer)
                                    
                            if (iCivic3 == 15): #decentralization
                                    if (teamPlayer.isHasTech(con.iEconomics)):
                                            iNewBaseStability -= 5
                                            #print("iNewBaseStability decentralization",iNewBaseStability, iPlayer)    
    Code:
                    if (iGameTurn >= con.tBirth[iPlayer]+15):
                            self.setGNPnew(iPlayer, self.getGNPnew(iPlayer) + (iEconomy + 4*iIndustry + 2*iAgriculture)/7)
                            if (iGameTurn % 3 == 2):
                                    iTempEconomyThreshold = self.getStability(iPlayer)
                                    iMaxShrink = 7
                                    iMaxGrowth = 3
                                    iNegativeFasterGrowth = (self.getGNPnew(iPlayer)-4)/3 - self.getGNPold(iPlayer)/3   #-1:-1 -2:-2 -3:-2 -4:-2 -5:-3 -6:-3 -7:-3 -8:-4 
                                    iNegativeNormalGrowth = (self.getGNPnew(iPlayer)-3)/3 - self.getGNPold(iPlayer)/3   #-1:-1 -2:-1 -3:-2 -4:-2 -5:-2 -6:-3 -7:-3 -8:-3 
                                    iNegativeSlowerGrowth = (self.getGNPnew(iPlayer)-1)/3 - self.getGNPold(iPlayer)/3   #-1: 0 -2:-1 -3:-1 -4:-1 -5:-2 -6:-2 -7:-2 -8:-3 
                                    
                                    iPositiveFasterGrowth = self.getGNPnew(iPlayer)/3 - self.getGNPold(iPlayer)/3   # 0: 0 +1: 0 +2: 0 +3:+1 +4:+1 +5:+1 +6:+2 +7:+2 +8:+2 +9:+3   
                                    iPositiveNormalGrowth = self.getGNPnew(iPlayer)/4 - self.getGNPold(iPlayer)/4       # 0: 0 +1: 0 +2: 0 +3: 0 +4:+1 +5:+1 +6:+1 +7:+1 +8:+2 +9:+2 
                                    iPositiveSlowerGrowth = self.getGNPnew(iPlayer)/5 - self.getGNPold(iPlayer)/5       # 0: 0 +1: 0 +2: 0 +3: 0 +4: 0 +5:+1 +6:+1 +7:+1 +8:+1 +9:+1 
    
                                    iNegativeGrowth = iNegativeNormalGrowth
                                    iPositiveGrowth = iPositiveNormalGrowth
                                    if (iPlayer == con.iEgypt or iPlayer == con.iIndia or iPlayer == con.iChina or iPlayer == con.iBabylonia): #counterbalance their stagnation due to the very early start
                                            iNegativeGrowth = iNegativeSlowerGrowth
                                    if (iPlayer == con.iNetherlands or iPlayer == con.iMali or iPlayer == con.iPortugal or iPlayer == con.iMongolia or iPlayer == con.iTurkey): #counterbalance their late start
                                            iNegativeGrowth = iPositiveSlowerGrowth
                                    if (iPlayer == con.iMali or iPlayer == con.iPortugal or iPlayer == con.iMongolia or iPlayer == con.iTurkey or iPlayer == con.iAmerica): #counterbalance their late start
                                            iNegativeGrowth = iNegativeFasterGrowth
                                    if (iPlayer == con.iJapan or iPlayer == con.iInca): #counterbalance their stagnation due to isolation
                                            iNegativeGrowth = iNegativeSlowerGrowth
                                    if (iPlayer == con.iIndia or iPlayer == con.iChina or iPlayer == con.iJapan or iPlayer == con.iKhmer or iPlayer == con.iMaya or iPlayer == con.iAztecs or iPlayer == con.iInca): #counterbalance their stagnation due to isolation
                                            iPositiveGrowth = iPositiveFasterGrowth
                                                              
                                    if (self.getGNPnew(iPlayer) < self.getGNPold(iPlayer)):
                                            self.setStability(iPlayer, self.getStability(iPlayer) + max(-iMaxShrink, iNegativeGrowth))
                                            #print("Stability - GNP check", iNegativeGrowth, iPlayer)
                                    elif (self.getGNPnew(iPlayer) >= self.getGNPold(iPlayer)):
                                            self.setStability(iPlayer, self.getStability(iPlayer) + min(iMaxGrowth, iPositiveGrowth))
                                            #print("Stability - GNP check", iPositiveGrowth, iPlayer)
                                    
                                    self.setParameter(iPlayer, iParEconomyE, True, self.getStability(iPlayer) - iTempEconomyThreshold)
    
    
                                    if (self.getGreatDepressionCountdown(iPlayer) == 0):   #great depression checked when GNP can be compared
                                            if (iCivic3 == 17 and teamPlayer.isHasTech(con.iCorporation)): #free market
                                                    if (not pPlayer.isGoldenAge()):
                                                            if ((iDifference > 11 and self.getGNPnew(iPlayer) > self.getGNPold(iPlayer)) or \
                                                                (iDifference > 6 and self.getGNPnew(iPlayer) > self.getGNPold(iPlayer) + 4)): #low wages and big growth
                                                                    self.setGreatDepressionCountdown(iPlayer, 8) #8 turns
                                                                    
                    if (self.getGreatDepressionCountdown(iPlayer) < 0):
                            self.setGreatDepressionCountdown(iPlayer, self.getGreatDepressionCountdown(iPlayer)+1)
                                                                    
                    iTempEconomyThreshold = iNewBaseStability
                    if (self.getGreatDepressionCountdown(iPlayer) > 0):
                            iNewBaseStability -= (15 + min(15, iDifference))
                            if (iPlayer == utils.getHumanID()):
                                    CyInterface().addMessage(iPlayer, False, con.iDuration, CyTranslator().getText("TXT_KEY_STABILITY_PERIOD", ()) + " " + CyTranslator().getText("TXT_KEY_STABILITY_GREAT_DEPRESSION", ()), "", 0, "", ColorTypes(con.iOrange), -1, -1, True, True)
                            #print("iNewBaseStability civic single 5: great depression",iNewBaseStability, iPlayer)
                            self.setGreatDepressionCountdown(iPlayer, self.getGreatDepressionCountdown(iPlayer)-1)
                            bQuit = False
                            if (self.getGreatDepressionCountdown(iPlayer) == 0): #just quit
                                    bQuit = True
                            if (self.getGreatDepressionCountdown(iPlayer) > 0 and self.getGreatDepressionCountdown(iPlayer) <= 7): #should last at least 3 turns 
                                    if ((iDifference < 5 and self.getGNPnew(iPlayer) <= self.getGNPold(iPlayer)) or iCivic3 != 17): #better wages and natural deflation, or no free market anymore
                                            bQuit = True
                                            
                            if (bQuit == True):
                                    self.setGreatDepressionCountdown(iPlayer, -30) ##quit from the spiral immediately and set turns of immunity
                                    bOtherDepressionAround = False
                                    for iLoopCiv in range(iNumPlayers):
                                            if (self.getGreatDepressionCountdown(iLoopCiv) > 0):
                                                    bOtherDepressionAround = True
                                    if (bOtherDepressionAround == False):
                                            for iLoopCiv in range(iNumPlayers):
                                                    if (iLoopCiv != iPlayer):
                                                            self.setGreatDepressionCountdown(iPlayer, -20) ##set turns of immunity for the other civs
    
                    if (iGameTurn % 3 == 2):
                            self.setGNPold(iPlayer, self.getGNPnew(iPlayer))
                            self.setGNPnew(iPlayer, 0)
    
                    if (self.getGreatDepressionCountdown(iPlayer) == 0 and iCivic3 != 18 and not pPlayer.isGoldenAge()):   #acquire only if there's no depression already and if it's not immune, no state property and no golden age
                            for iLoopCiv in range(iNumPlayers):
                                    if (teamPlayer.isOpenBorders(iLoopCiv)):
                                            if (self.getGreatDepressionCountdown(iLoopCiv) > 0):
                                                    if (iCivic3 == 16): #mercantilism
                                                            iNewBaseStability -= 7
                                                    else:
                                                            iNewBaseStability -= 10
                                                    #print("iNewBaseStability: acquired great depression",iNewBaseStability, iPlayer)                        
                                                    if (iPlayer == utils.getHumanID()):
                                                            CyInterface().addMessage(iPlayer, False, con.iDuration, \
                                                                                     CyTranslator().getText("TXT_KEY_STABILITY_GREAT_DEPRESSION_INFLUENCE", (gc.getPlayer(iLoopCiv).getCivilizationDescription(0),)), \
                                                                                     "", 0, "", ColorTypes(con.iOrange), -1, -1, True, True)
                                                    break #just once is enough
             
                    
                    if (teamPlayer.isHasTech(con.iCommunism)): #post communism
                            if (iCivic3 == 18): #state prop
                                    self.setStatePropertyCountdown(iPlayer, -1) #has state property
                            if (self.getStatePropertyCountdown(iPlayer) == -1 and iCivic3 != 18): #switched
                                    self.setStatePropertyCountdown(iPlayer, 8) #8 turns
                            if (self.getStatePropertyCountdown(iPlayer) > 0):
                                    iNewBaseStability -= 25
                                    self.setStatePropertyCountdown(iPlayer, self.getStatePropertyCountdown(iPlayer)-1)
                                    if (iPlayer == utils.getHumanID()):
                                            CyInterface().addMessage(iPlayer, False, con.iDuration, CyTranslator().getText("TXT_KEY_STABILITY_PERIOD", ()) + " " + CyTranslator().getText("TXT_KEY_STABILITY_POST_COMMUNISM", ()), "", 0, "", ColorTypes(con.iOrange), -1, -1, True, True)
                                    #print("iNewBaseStability civic single 6: post communism",iNewBaseStability, iPlayer)
                    self.setParameter(iPlayer, iParEconomy1, False, iNewBaseStability - iTempEconomyThreshold)
    
                    iTempCivicThreshold = iNewBaseStability
                    if (teamPlayer.isHasTech(con.iDemocracy)): #transition to democracy
                            if (iCivic0 == 0 or iCivic0 == 1 or iCivic0 == 3): #despotic governments
                                    self.setDemocracyCountdown(iPlayer, -1) #has a desp. gov.
                            if (self.getDemocracyCountdown(iPlayer) == -1 and iCivic0 == 4): #switched to universal suffrage
                                    self.setDemocracyCountdown(iPlayer, 7) #7 turns
                            if (self.getDemocracyCountdown(iPlayer) > 0):
                                    iNewBaseStability -= 20
                                    self.setDemocracyCountdown(iPlayer, self.getDemocracyCountdown(iPlayer)-1)
                                    if (iPlayer == utils.getHumanID()):
                                            CyInterface().addMessage(iPlayer, False, con.iDuration, CyTranslator().getText("TXT_KEY_STABILITY_PERIOD", ()) + " " + CyTranslator().getText("TXT_KEY_STABILITY_DEMOCRACY", ()), "", 0, "", ColorTypes(con.iOrange), -1, -1, True, True)
                                    #print("iNewBaseStability civic single 7: transition to democracy",iNewBaseStability, iPlayer)
                    self.setParameter(iPlayer, iParCivics1, False, iNewBaseStability - iTempCivicThreshold)


    I'm not too sure, I remember seeing something like this somewhere that I cannot remember; but I do know that the python file CityNameManager.py has a large list of city names.

    I'm clueless about the rest.

    I also highly reccommend Baldyr's custom functions, Custom.py, the thread is here, they are very useful, and will probabily help you.
     
  3. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    Dynamic names are in C++

    civDynamicNames array containing the actual name keys is located in CvRhyes.cpp, below are two related arrays. There's quite a few functions involved in changing of names, but the actual algorithm is in processCivNames function in CvPlayer.cpp.

    Adding / replacing civs a big topic, you can technically add new ones, it's just more work. There's no short answer for everything, in RFC these things are scattered over 30 different files.

    For starters, most C++ stuff to be modified is in CvRhyes. You can copy'n'paste maps there, as well as edit descriptions, start dates etc. A lot of other stuff is hardcoded in a few cpp files - if you're replacing maya, search for "MAYA" string in CvGameCoreDLL folder to see all files involved.

    In Python files, Consts.py contains most civ definitions, much like CvRhyes. CityNameManager contains city maps. AIWars contains war maps. Nearly every .py file contains "something" that needs to be changed though. Again, use file search to find stuff from Const.py, e.g. "iMaya".
     
  4. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    Civics

    1st/2nd: Pi answered this, great depression and transition effects are in Stability.py as well, just look for the keywords

    3rd: no, you'd have to code it in C++

    4th: many ways to do this, the easiest would be to enable USE_CANNOT_CONSTRUCT_CALLBACK in PythonCallbackDefines.xml, then you can play with the "cannotConstruct" function in Python/CvGameUtils.py (copy from BTS folder); I mean adding checks like "if iCivic == X and eBuilding == Y: return True" using Rhye's enums from Consts.py.
     
  5. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Many thanks! Your link to Baldyr's file also brought many valuable insights :)

    Thank you very much! I'll dive into the C++ files right away :)

    Then it's probably not worth the effort :D
     
  6. fdgsgds

    fdgsgds Mustard Enthusiast

    Joined:
    Feb 16, 2009
    Messages:
    558
    Location:
    The Empire State
    No! I like your ideas and perhaps you should try to find someone to work with you :):)
     
  7. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    That's nice to hear and very motivating, thanks :)

    Actually I'm very eclectic here: implementing many ideas that are part of other mods (for example, adding Zoroastrianism like in RFCC and Protestantism like in Panopticon's mod), making little changes to some buildings (+1 merchant slot for the Viking's trading post) and so on.

    The new civics are the only thing I completely thought out on my own. If you're interested, that's how it looks like:
    Spoiler :

    The categories are now:

    GOVERNMENT: Tyranny, Monarchy, Theocracy, Autocracy, Republic
    ORGANISATION: Direct Rule, Vassalage, Absolutism, Representation, Parliamentarism
    SOCIETY: Tribalism, Aristocracy, Socialism, Totalitarism, Capitalism
    ECONOMY: Self-sufficiency, Serfdom, Mercantilism, State Property, Free Market
    RELIGION: Animism, Pantheon, Patriarchate, State Church, Laicism

    Don't worry too much about the upkeep, often I didn't use the upkeep I planned and went with what RFC uses for comparable civics.

    MONARCHY
    Requires: Monarchy
    Upkeep: Low
    Effect: +1 happiness for every military unit in your cities

    THEOCRACY
    Requires: Theology
    Upkeep: Medium
    Effect: +3 experience for units built in cities with state religion

    REPUBLIC
    Requires: Philosophy
    Upkeep: High
    Effect: +50% great person birth and 100% faster cottage growth

    AUTOCRACY
    Requires: Nationalism
    Upkeep: Medium
    Effect: Can draft military units, +2 happiness with barracks

    VASSALAGE
    Requires: Feudalism
    Upkeep: Low
    Effect: +2 experience for all units, -25% number of cities maintenance, +25% city distance maintenance

    ABSOLUTISM
    Requires: Civil Service
    Upkeep: High
    Effect: +50% production and commerce in your capital

    REPRESENTATION
    Requires: Constitution
    Upkeep: High
    Effect: +3 research per specialist, -50% city distance maintenance

    PARLIAMENTARISM
    Requires: Democracy
    Upkeep: Medium
    Effect: +1 production in towns, +3 happiness in your three biggest cities, +1 free specialist

    SERFDOM
    Requires: Masonry
    Upkeep: Medium
    Effect: can sacrifice population to hurry production

    MERCANTILISM
    Requires: Banking
    Upkeep: High
    Effect: no foreign trade routes, +2 commerce in workshops, +1 free specialist, no foreign corporations

    FREE MARKET
    Requires: Economics
    Upkeep: Low
    Effect: +1 trade route, +50% commerce on trade routes, -50% corporation maintenance

    STATE PROPERTY
    Requires: Communism
    Upkeep: High
    Effect: +10% production, +1 food and production in workshops, no number of cities maintenance, no corporation effects

    ARISTOCRACY
    Requires: Monarchy
    Upkeep: Low
    Effect: +1 commerce in farms*, free military units

    CAPITALISM
    Requires: Liberalism
    Upkeep: Medium
    Effect: +2 commerce in towns, can spend gold to finish production

    SOCIALISM
    Requires: Communism
    Upkeep: High
    Effect: unlimited merchants, artists, scientists and engineers, +100% culture

    TOTALITARISM
    Requires: Fascism
    Upkeep: Low
    Effect: +25% unit production, -50% war weariness

    PANTHEISM
    Requires: Polytheism
    Upkeep: Low
    Effect: no state religion, +2 happiness with pagan temple, (unable to build temples or monasteries)

    PATRIARCHATE
    Requires: Monotheism
    Upkeep: High
    Effect: +25% building production in cities with state religion, missionaries can be built without monasteries

    STATE CHURCH
    Requires: Divine Right
    Upkeep: Medium
    Effect: +25% unit production in cities with state religion, no foreign religion spread, +1 happiness with state religion

    LAICISM
    Requires: Liberalism
    Upkeep: Low
    Effect: no state religion, +10% research, no penalties for different religions in your cities

    *I already had also +1 food here, but the AI ended up building only farms, which hurts them in the long run


    I also have new questions:
    How does the AI decide which civics to use? Can it "comprehend" each civic's abilities or do I have to set that somewhere. I already ran some games with 3000BC America to see how they play, and most of the time they make reasonable choices, but that could be attributed to the fact that many of my civics replace old ones with comparable abilities (like Universal Suffrage -> Parliamentarism).

    How does the AI decide which improvements to build? Most of all, does it factor in that cottages can grow? I sometimes think this is already a problem in standard RFC where the AI plasters its grassland with workshops and only techs very slowly.
    I ask because I gave farms +1 commerce with the Aristocracy civic, and then saw a Germany with ZERO cottages and farms everywhere.

    Edit: a new problem came up while I was replacing Confucianism with Zoroastrianism. Changing the religion's symbol as a button was no problem. However, in the city bar and civ list, I still see the Confucianism symbol. Where can I edit that?

    Btw: The game becomes interesting when China gets no early religion. Now they have rivaling Buddhism and Taoism, which is way more interesting than the fight between the rather interchangeable Confucianism/Taoism (I know they're actually quite different :p).
     
  8. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    The AI makes civic choices based on their features, so you don't have to do anything here. You can use AIValue to fine tune it but normally there's no reason to.

    Same with improvements, and the AI choice was good, I'd do the same, much like I abuse farms in RFCE. You might see the AI building cottages with different civics.

    Religion icons are in Assets/res/fonts
     
  9. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Fonts? I'd never have thought of that. Thanks again :)

    I still fear the AI will put farms everywhere and never realise that if it constructs cottages, switches to Capitalism and waits, would get a much higher techrate. Although in my America testruns, the techrate seems to be the same as in regular RFC, so maybe I think to much into it.
     
  10. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    New questions:

    After I've done everything that's achievable via XML/Python, I wanted to continue with the DLL. I followed this guide to set up my IDE, however, I'm getting this error when I want to compile:
    This happens even if I don't change anything.

    The error refers to this part of CvGameCoreDLL.h:
    Code:
    //
    // Boost Python
    //
    # include <boost/python/list.hpp>
    # include <boost/python/tuple.hpp>
    # include <boost/python/class.hpp>
    # include <boost/python/manage_new_object.hpp>
    # include <boost/python/return_value_policy.hpp>
    # include <boost/python/object.hpp>
    # include <boost/python/def.hpp>
    What did I do wrong? Am I missing something? Or did I make an error in configuring my IDE?
     
  11. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    I can't really relate to the above guide since I used the other one for MVC 2008 Express, but have you copied the Python/boost folders from the BTS CvGameCoreDLL folder? You should have Python24 and Boost-1.32.0 folders inside your mod's CvGameCoreDLL folder, Rhye's files alone are not enough.
     
  12. Panopticon

    Panopticon Utilitarian

    Joined:
    Aug 4, 2007
    Messages:
    1,434
    Location:
    Ireland
    Leoreth, you need to include some folders that aren't in the CvGameCoreDLL that comes with RFC. Do you have the Boost-1.32.0 and Python24 folders in your project folder, along with all the cpp and h files? If not, you should copy them from your Beyond The Sword\CvGameCoreDLL folder.
     
  13. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Thank you again. I'll see how far I get until the next problem pops up :)
     
  14. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Next problem popped up :D
    Literally. I got a python exception popup ;)

    Here it is:


    I don't know when the error occured first, because I had foolishly turned python exceptions invisible. So I noticed only later that several things in the "setup" method of RiseAndFall.py didn't work, like distributing starting gold and setting the right early leaders. So I'm completely clueless what caused this problem. If I read the error message correctly, somethings wrong either in RiseAndFall.py or Costs.py, as the code crashes on "setEarlyLeaders". I don't know what "unsubscriptable object" means, though, but I guess it cannot access tEarlyLeaders properly. But I wonder why, because to me it looks flawless:
    Code:
    tEarlyLeaders = (
    (iRamesses), 
    (iAsoka),
    (iQin_Shi_Huang),
    (iGilgamesh),
    (iPericles),
    (iCyrus),
    (iElishat),
    (iJulius_Caesar),
    (iJimmu),
    (iZara_Yaqob),
    (iPacal),
    (iRagnar),
    (iAbu_Bakr),
    (iSuryavarman),
    (iIsabella),
    (iCharlemagne),
    (iAlfred),
    (iCharles),
    (iYaroslav),
    (iWillem_Van_Oranje),
    (iMansa_Musa),
    (iAfonso),
    (iHuayna_Capac),
    (iGenghis_Khan),
    (iMontezuma),
    (iMehmed),
    (iWashington))
    So there must be something else in those Python files ... it drives me crazy.
     
  15. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Are you sure you posted the correct version of RiseAndFall? Because the line #723 does not seem to be in setEarlyLeaders(), but rather setupBirthTurnModifiers():
    Code:
            def setupBirthTurnModifiers(self):
                    for iCiv in range(iNumPlayers):
                            if (iCiv >= iGreece and not gc.getPlayer(iCiv).isHuman()):
                                    self.setBirthTurnModifier(iCiv, (gc.getGame().getSorenRandNum(11, 'BirthTurnModifier') - 5)) # -5 to +5
                    #now make sure that no civs spawn in the same turn and cause a double "new civ" popup
                    for iCiv in range(iNumPlayers):
                            if (iCiv > utils.getHumanID() and iCiv < iAmerica):
                                    for j in range(iNumPlayers-1-iCiv):
                                            iNextCiv = iCiv+j+1
                                            if (con.tBirth[iCiv]+self.getBirthTurnModifier(iCiv) == con.tBirth[iNextCiv]+self.getBirthTurnModifier(iNextCiv)):
                                                    [COLOR="Red"]self.setBirthTurnModifier(iNextCiv, (self.getBirthTurnModifier(iNextCiv)+1))[/COLOR]
    Anyways, I'm only a beginner at Python myself, but an "unsubscriptable object" sounds to me like the code is trying to access something like a list, a tupple or a dictionary, but gets an integer, a string or something else instead. So check your variables.

    If it were a case of the "subscriptable object" lacking an entry the exception would probably have been "out of range" or something like that.

    What exactly have you changed, by the way?
     
  16. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Line 723 is this one:
    Code:
            def setEarlyLeaders(self):
                    for i in range(iNumActivePlayers):
                            [COLOR="Red"]if (tEarlyLeaders[i] != tLeaders[i][0]):[/COLOR]
                                    if (not gc.getPlayer(i).isHuman()):
                                            gc.getPlayer(i).setLeader(tEarlyLeaders[i])
                                            print ("leader starting switch:", tEarlyLeaders[i], "in civ", i)
    Did you look into the files I appended to my post?

    The problem seems to be either with tEarlyLeaders or tLeaders, but both are one- resp. two-dimensional arrays in Consts.py as used here.

    The only changes realized in those two Python files are different spawn dates for Netherlands and Carthage, different spawn plots for Carthage and Vikings, new core/normal area for Carthage (including the Levant now), and changes to the Dutch and Carthaginian starting units and techs to reflect their new spawn date.
    I also added some extra leaders to Consts.py and changed tEarlyLeaders, tLeaders and tLateLeaders accordingly. But this feature already worked during the modding process. Oh, and I also changed the part of RiseAndFall that manages leader switches to allow four leaders for certain civs as described by Panopticon.
     
  17. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Yeah, strange... :confused:

    The problem is with one (or both of) the tuples tLeaders and tEarlyLeaders. Either you have misspelled one of them or something, or there is an issue with their contents. Add this line to your code for debugging:
    Code:
            def setEarlyLeaders(self):
                    for i in range(iNumActivePlayers):
                            [COLOR="Red"]print ("setEarlyLeaders()", i)[/COLOR]
                            if (tEarlyLeaders[i] != tLeaders[i][0]):
                                    if (not gc.getPlayer(i).isHuman()):
                                            gc.getPlayer(i).setLeader(tEarlyLeaders[i])
                                            print ("leader starting switch:", tEarlyLeaders[i], "in civ", i)
    Now run the code and look at the Debug Log. It should print out all the Civ's index numbers up to the one causing the problem. Then you look at the entries for that Civ.
     
  18. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    Line 1551 in Consts.py

    Change:
    (iSuryavarman),

    back to:
    (iSuryavarman,),

    (1) is single value in parentheses and (2) is an actual tuple containing 1 value, hence the unsubscriptable object error.
     
  19. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,616
    Gender:
    Male
    Location:
    Kamiyama
    Thanks embryodead. Python seems to require much carefulness compared to more type-safe languages :crazyeye:

    Also thanks for your effort Baldyr :)
     
  20. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    You're welcome, and I'm sure we would have found the problem even without the valiant efforts of embryodead (well spotted, by the way! :goodjob:).

    The problem, as the man himself llustrated, was that the tuple tLeaders is supposed to be comprised of other tuples. And a tuple, in Python, must have at least one comma - unless its empty.

    This is important to remember, and I've been there myself a couple of times. (The sad thing is that I forget these things. :p)
     

Share This Page