Quick Modding Questions Thread

I like the new resource icons in that screenshot.
 
a very basic question

can I edit the basic "it's too crowded" malus to give -2 unhealthines per pop?
 
Can you use traits to increase the rate of the building wonders? Like Organised boosts the production of courthouses.

I tried and I cant see the effect on the unit card, but there no crash when i load the XML. Is it hidden?
 
Can you use traits to increase the rate of the building wonders? Like Organised boosts the production of courthouses.

I tried and I cant see the effect on the unit card, but there no crash when i load the XML. Is it hidden?

iMaxGlobalBuildingProductionModifier increases build rate for Wonders.
 
Can you use traits to increase the rate of the building wonders? Like Organised boosts the production of courthouses.

I tried and I cant see the effect on the unit card, but there no crash when i load the XML. Is it hidden?
Industrious trait?
 
You talk about wonders, Courthouses (ordinary city improvements), and units (unit cards?). I am confused.
 
You talk about wonders, Courthouses (ordinary city improvements), and units (unit cards?). I am confused.
Sorry this was me being half asleep when writing the post. Individual Units and buildings gain faster production depending on traits,(settlers for expansive, theatre for creative) can individual wonders gain such a boost from traits? I've tested it, but i'm such a noob i'm not sure if its my incompetence or it it doesn't fundamentally work, but it didn't work for me, even though the game loaded fine after i edited the XML.
 
Sorry this was me being half asleep when writing the post. Individual Units and buildings gain faster production depending on traits,(settlers for expansive, theatre for creative) can individual wonders gain such a boost from traits? I've tested it, but i'm such a noob i'm not sure if its my incompetence or it it doesn't fundamentally work, but it didn't work for me, even though the game loaded fine after i edited the XML.
You should be able to do it the same way all the other buildings do it. As in just add your trait to <ProductionTraits> on the building.
 
Hiya, I'm trying to limit the number of Warriors to 2 per player.

My attempt to do this results in the game not running any Python at all upon map start. I've probably made a horrendous syntax error.

Can anyone help, please? Thanks!

Python:
  def cannotTrain(self,argsList):
    pCity = argsList[0]
    eUnit = argsList[1]
    bContinue = argsList[2]
    bTestVisible = argsList[3]
    bIgnoreCost = argsList[4]
    bIgnoreUpgrades = argsList[5]


    ## New Code
    if eUnit == gc.getInfoTypeForString('UNIT_WARRIOR'):
      pPlayer = gc.getPlayer(iPlayer)
      if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNIT_WARRIOR')) == 2:
        return True
    return False

EDIT:

My code now looks like this. Python now runs but the code does not appear to do anything. Any help most welcome.

Python:
def cannotTrain(self,argsList):
    pCity = argsList[0]
    eUnit = argsList[1]
    bContinue = argsList[2]
    bTestVisible = argsList[3]
    bIgnoreCost = argsList[4]
    bIgnoreUpgrades = argsList[5]


    ## New Code
    if eUnit == gc.getInfoTypeForString('UNIT_WARRIOR'):
      pPlayer = gc.getActivePlayer()
      if pPlayer.getUnitClassCountPlusMaking('UNITCLASS_WARRIOR') > 1:
        return True
    return False
 
Last edited:
Hiya, I'm trying to limit the number of Warriors to 2 per player.

Why don't you just use the XML only solution in CIV4UnitClassInfos.xml? :confused:

XML:
        <UnitClassInfo>
            <Type>UNITCLASS_WARRIOR</Type>
            <Description>TXT_KEY_UNIT_WARRIOR</Description>
            <iMaxGlobalInstances>-1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>2</iMaxPlayerInstances>
            <iInstanceCostModifier>0</iInstanceCostModifier>
            <DefaultUnit>UNIT_WARRIOR</DefaultUnit>
        </UnitClassInfo>
 
I'm working on making it a limit on a certain group of units. "You can only have up to X of any of the following". The Warrior is just a stand-in while I figure it out. That means it's gotta be Python.
 
I'm working on making it a limit on a certain group of units. "You can only have up to X of any of the following". The Warrior is just a stand-in while I figure it out. That means it's gotta be Python.
Does group of units mean unit type or something else?
 
Does group of units mean unit type or something else?
I'm trying to write something like this:

Python:
  def cannotTrain(self,argsList):
    pCity = argsList[0]
    eUnit = argsList[1]
    bContinue = argsList[2]
    bTestVisible = argsList[3]
    bIgnoreCost = argsList[4]
    bIgnoreUpgrades = argsList[5]


    ## New Code
    if eUnit == gc.getInfoTypeForString('UNIT_WARRIOR') or eUnit == gc.getInfoTypeForString('UNIT_ARCHER'):
      pPlayer = gc.getActivePlayer()
      if (pPlayer.getUnitClassCountPlusMaking('UNITCLASS_WARRIOR') + pPlayer.getUnitClassCountPlusMaking('UNITCLASS_ARCHER')) > 2:
        return True
    return False

Which would, in theory, allow each player to have 1 Warrior, 2 Warriors, 1 Archer, 2 Archers, or 1 Warrior and 1 Archer, but no more.

But it doesn't do anything at all. I've probably written it wrong.
 
Last edited:
I'm trying to write something like this:

Python:
  def cannotTrain(self,argsList):
    pCity = argsList[0]
    eUnit = argsList[1]
    bContinue = argsList[2]
    bTestVisible = argsList[3]
    bIgnoreCost = argsList[4]
    bIgnoreUpgrades = argsList[5]


    ## New Code
    if eUnit == gc.getInfoTypeForString('UNIT_WARRIOR') or eUnit == gc.getInfoTypeForString('UNIT_ARCHER'):
      pPlayer = gc.getActivePlayer()
      if (pPlayer.getUnitClassCountPlusMaking('UNITCLASS_WARRIOR') + pPlayer.getUnitClassCountPlusMaking('UNITCLASS_ARCHER')) > 2:
        return True
    return False

Which would, in theory, allow each player to have 1 Warrior, 2 Warriors, 1 Archer, 2 Archers, or 1 Warrior and 1 Archer, but no more.

But it doesn't do anything at all. I've probably written it wrong.

Try something like this:

Python:
        <UnitClassInfo>
            <Type>UNITCLASS_BASE_UNITS</Type>
            <Description>TXT_KEY_UNIT_BASE_UNITS</Description>
            <iMaxGlobalInstances>-1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>2</iMaxPlayerInstances>
            <iInstanceCostModifier>0</iInstanceCostModifier>
            <DefaultUnit>UNIT_BASE_WARRIOR</DefaultUnit>
        </UnitClassInfo>
       
       
        <UnitInfo>
            <Class>UNITCLASS_BASE_UNITS</Class>
            <Type>UNIT_BASE_WARRIOR</Type>
            <UniqueNames>
            </UniqueNames>
            ...
       
        <UnitInfo>
            <Class>UNITCLASS_BASE_UNITS</Class>
            <Type>UNIT_BASE_ARCHER</Type>
            <UniqueNames>
            </UniqueNames>
            ...

And of course the UNIT_BASE_WARRIOR could be designed exactly like the UNIT_WARRIOR, etc.
 
Try something like this:

Python:
        <UnitClassInfo>
            <Type>UNITCLASS_BASE_UNITS</Type>
            <Description>TXT_KEY_UNIT_BASE_UNITS</Description>
            <iMaxGlobalInstances>-1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>2</iMaxPlayerInstances>
            <iInstanceCostModifier>0</iInstanceCostModifier>
            <DefaultUnit>UNIT_BASE_WARRIOR</DefaultUnit>
        </UnitClassInfo>
      
      
        <UnitInfo>
            <Class>UNITCLASS_BASE_UNITS</Class>
            <Type>UNIT_BASE_WARRIOR</Type>
            <UniqueNames>
            </UniqueNames>
            ...
      
        <UnitInfo>
            <Class>UNITCLASS_BASE_UNITS</Class>
            <Type>UNIT_BASE_ARCHER</Type>
            <UniqueNames>
            </UniqueNames>
            ...

And of course the UNIT_BASE_WARRIOR could be designed exactly like the UNIT_WARRIOR, etc.
That's an interesting solution, but wouldn't it create a whole heap of problems if every single unit type in the game had to be reclassified as a new unit class?? I think a Python solution would not require any modification to the unit classes at all.

I just can't get getUnitClassCountPlusMaking() formatted correctly. I think.

Any ideas what I've done wrong, please?
 
Any ideas what I've done wrong, please?
I'm guessing that, mainly, you're missing getInfoTypeForString calls for the UNITCLASS_... strings. I'm surprised that you're not getting an exception (popup or PythonErr.log, if enabled in CivilizationIV.ini); getUnitClassCountPlusMaking expects an integer. Well, perhaps the string is getting converted implicitly somehow.

Also, the player should be the city owner, I think: gc.getPlayer(pCity.getOwner())
The "active" player is always the human player (the one currently taking their turn in a Hotseat or PBEM game, the one on whose machine the code is being executed in a network game).

Edit: And USE_CANNOT_TRAIN_CALLBACK needs to be set in PythonCallbackDefines.xml. But I guess you've verified that cannotTrain is getting called. (Something like print "cannotTrain call" should suffice; gets written to PythonDbg.log if logging is enabled in CivilizationIV.ini.)
 
Last edited:
What is in the PythonCallback argsList for Events?

Like, some of the methods in CvRandomEventInterface.py have this:

iButton = argsList[0]
iData1 = argsList[1]
iData2 = argsList[2]
iData3 = argsList[3]
szText = argsList[4]
bOption1 = argsList[5]
bOption2 = argsList[6]

and others have this:

iEvent = argsList[0]
kTriggeredData = argsList[1]

So, how do we know what is in argsList in general, if we are making our own Event Callback?
 
Back
Top Bottom