Awesome. Now I'm a little sketchy on which folders you can tinker with and have them only affect a custom scenario and not the rest of the game. Are there folders where the command line "if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):" wouldn't work?
It should work in pretty much any python file.
The call is actually "if
CyGlobalContext().getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):", but since CyGlobalContext() is called so often in many files Kael set gc = CyGlobalContext() at the top of them. If you want to use this conditional in a file where it is not defined so then you must either write it out every time or add that line near the top.
It seems a lot easier to keep track of scenario-specific things if you keep them all in ScenarioFunctions.py though.
Few other queries about my "Auric Ascends" scenario, as well.
- Acheron's Wyrmhold causes -5 happiness in the city should a Temple of the Hand be built. I assume that setting iConquestProb to 0 on Acheron's Wyrmhold would cause it to automatically be destroyed when captured, solving the problem, but as I understand it this would apply to all games played and not just the scenario. Solutions?
The easiest way would be to use the game option to disable Acheron, but you probably don't want to disable Drifa in the process.
You could place this under
def onCityAcquired(self, iPreviousOwner, iNewOwner, pCity, bConquest, bTrade):
Code:
if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
if pCity.getNumRealBuilding(gc.getInfoTypeForString('BUILDING_WYRMHOLD_ACHERON')) > 0:
pCity.setNumRealBuilding(gc.getInfoTypeForString('BUILDING_WYRMHOLD_ACHERON'), 0)
That would remove the wonder whenever a new player captures the city. You could also add another conditional if you wanted that to only be the case for the Illians, players following the White Hand religion, etc.
- What's the easiest way to have an NPC city refuse to accept its Civ's state religion? Falamar has a little problem with squidloving loonies spreading throughout his empire, but he's tolerating none of that baloney in his own capitol.
I don't know about blocking the spread of the religion, but it would be simple enough to remove the religion from his capital every turn.
In ScenarioFunctions.py, under
def doTurn(self): (or a scenario specific doTurn function called from there, if the code gets complicated and you want it to be organized like all the other scenarios)
Code:
elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
iFalamarPlayer = cf.getLeader(gc.getInfoTypeForString('LEADER_FALAMAR'))
pCity = gc.getPlayer(iFalamarPlayer).getCapitalCity()
iOverlords = gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS')
pCity.setHasReligion(iOverlords, False, True, True)
for i in range(gc.getNumBuildingInfos()):
if pCity.getNumBuilding(i) > 0:
if gc.getBuildingInfo(i).getPrereqReligion() == iOverlords:
if not isWorldWonderClass(gc.getBuildingInfo(i).getBuildingClassType()):
pCity.setNumRealBuilding(i, 0)
Edit: You could also add this code to
def onReligionSpread(self, argsList): in CvEventManager.py to remove the religion whenever it spreads to Falamar's Capital. There is not yet an equivalent call in ScenarioFunctions.py though, so if you want to keep the scenario-specific things together you would have to create one and edit CvEventManager.py to make it be called.
Code:
iOverlords = gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS')
if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
if pSpreadCity.isCapital():
if pPlayer.getLeaderType() == gc.getInfoTypeForString('LEADER_FALAMAR'):
if iReligion == iOverlords:
pSpreadCity.setHasReligion(iOverlords, False, True, True)
- Where might I find the folder governing the opening text / illustration that pops up at the beginning of any regular scenario?
The code that controls those popups is found in ScenarioFunctions.py under
def gameStart(self):
Code:
if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_AGAINST_THE_GREY):
pPlayer = gc.getPlayer(0)
if pPlayer.isHuman():
gc.getPlayer(0).setAlignment(gc.getInfoTypeForString('ALIGNMENT_GOOD'))
self.addPopupWB(CyTranslator().getText("TXT_KEY_WB_AGAINST_THE_GREY_INTRO_MALAKIM",()), 'art/interface/popups/Against the Grey.dds')
else:
gc.getPlayer(1).setAlignment(gc.getInfoTypeForString('ALIGNMENT_EVIL'))
self.addPopupWB(CyTranslator().getText("TXT_KEY_WB_AGAINST_THE_GREY_INTRO_CALABIM",()), 'art/interface/popups/Against the Grey.dds')
The TXT_KEY's are can be defined in pretty much any of the files found in the
Assets\XML\Text folder. Kael put everything in one file called CIV4GameText_FFH2.xml, which is huge. I placed all of my changed in Magister_CIV4GameText_FFH2.xml, which is sill pretty big. Tholal put the various TXT_KEY's requires for More Naval AI in 71 different much smaller .xml files, many of them borrowed directly from modcomps he merged into his modmod.
I'm not sure of the exact order the game reads these things in. I think it goes in alphabetical order, with whatever it reads last overriding what it read before. I know that there are many TXT_KEY's in CIV4GameText_FFH2.xml ad Magister_CIV4GameText_FFH2.xml that share the same name, and that the ones in Magister_CIV4GameText_FFH2.xml are what are used in the game.
You could include all the TXT_KEY's used in your scenario in one new xml file in that folder. You could also just write out the text you want displayed within those quotation marks and not bother with TXT_KEY's, if you don't mind the same words being used in ll languages. The code could be rather unwieldy if you include a long string of text that way though.
The path of the artwork in this case is 'art/interface/popups/Against the Grey.dds', but you would presumably want to change that. You could ass your own artwork, or reuse the artwork from another scenario like Return of Winter, Blood of the Angels, or Mulcarn Reborn. I was about to suggest using the popup for the Auric Ascended unit, but I'm thinking now that its lower resolution might stop it from working with self.addPopupWB(). (It would work with cf.addPopup, but then the popup window would be smaller and off to the side like an event rather than an opening screen.)
- Can Python change several specific plots/terrains/landmark captions at once? What I'm aiming for here is a tropical valley in the frozen northlands, walled-off by mountains and kept warm by Bhall's blessings / numerous Fire Nodes. What I'd love to do is have a Jungle Altar captioned "Tribute Unto Bhall" that, when taken, switches captions to "Tribute Unto Mulcarn" and changes all the jungle/grasslands into snowy trees/tundra. A short text popup would be an added bonus. Too ambitious?
It does not sound too ambitious, or even particularly difficult.
You can set the initial signs in the scenario file. The original versions of the scenarios had these set for the various unique improvements, but I removed those. You can still see plenty of examples at the bottom of
KE huge ICE Empires v1.1 for MagisterModmod.CivBeyondSwordWBSave though.
Code:
BeginSign
plotX=13
plotY=21
playerType=-1
caption=Tomb of Sucellus
EndSign
The plotX and plotY obviously refer to the coordinates of the tile that bears the caption, and the caption is what you want it to say. (Note: If the caption is too long it will get truncated. I don't think the captions you want are too long, but I'm not sure what the limit is other than that "Guardian of the Pristinus Pass" won't all fit.)
When playerType is set to -1 then it is a landmark, in black, visible to everyone, and unable to be removed without resorting to python. If you set it to a particular player's index then it will be placed in that player's colors, be visible only to that player's team, and that player will be able to remove it just like the signs he might add himself using
alt + s.
For the change in signs and the popup, you can look for examples in ScenarioFunction.py under def onMoveWarningPost(self, pCaster, pPlot):, elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_LORD_OF_THE_BALORS):, around line 2329 in my modmod.
Code:
elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_LORD_OF_THE_BALORS):
iPlayer = pCaster.getOwner()
pPlayer = gc.getPlayer(iPlayer)
if pPlayer.isHuman():
if pPlot.at(33,14):
pPlot.setImprovementType(-1)
CyEngine().addLandmark(pPlot, "The Conquerers' Pass")
szText = CyTranslator().getText("TXT_KEY_WB_LORD_OF_THE_BALORS_CONQUERERS_PASS",())
if pPlayer.getLeaderType() == gc.getInfoTypeForString('LEADER_KEELYN'):
szText = CyTranslator().getText("TXT_KEY_WB_LORD_OF_THE_BALORS_CONQUERERS_PASS_KEELYN",())
cf.addPlayerPopup(szText, iPlayer)
If there is already a landmark in place, I believe that you would have to include the line
CyEngine().removeLandmark(pPlot) before
CyEngine().addLandmark(pPlot, "The Conquerers' Pass")
If you want the captions be be only for a specific player, then you can use
CyEngine().removeSign(pPlot, iPlayer) before
CyEngine().addSign(pPlot, iPlayer, "Tribute Unto Mulcarn") instead.
As you can see, the code already shows a text popup to the player whose unit entered the plot and changed the signs.
You can place this code under
def onMoveJungleAltar(self, pCaster, pPlot): just as easily as under
def onMoveWarningPost(self, pCaster, pPlot):.
The hardest part of the terraforming would be deciding what tiles needs to change. You could change the whole map, you could change only specific hard coded tiles, or you could loop through tiles nearby. I'm going to assume you want the later, and to make things easier I'll assume that the area to be terraformed is a square with the jungle altar at its center.
You could just place this code right below the code that changes the landmarks:
Code:
iSnow = gc.getInfoTypeForString('TERRAIN_SNOW')
iGlacier = gc.getInfoTypeForString('TERRAIN_GLACIER')
iFlames = gc.getInfoTypeForString('FEATURE_FLAMES')
iFloodPlains = gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS')
iForest = gc.getInfoTypeForString('FEATURE_FOREST')
iJungle = gc.getInfoTypeForString('FEATURE_JUNGLE')
iScrub = gc.getInfoTypeForString('FEATURE_SCRUB')
iSmoke = gc.getInfoTypeForString('IMPROVEMENT_SMOKE')
iNodeFire = gc.getInfoTypeForString('IMPROVEMENT_MANA_FIRE')
iBonusFire = gc.getInfoTypeForString('BONUS_MANA_FIRE')
iNodeIce = gc.getInfoTypeForString('IMPROVEMENT_MANA_ICE')
iBonusIce = gc.getInfoTypeForString('BONUS_MANA_ICE')
iX = pPlot.getX()
iY = pPlot.getY()
for iiX in range(iX-3, iX+4, 1):
for iiY in range(iY-3, iY+4, 1):
pLoopPlot = CyMap().plot(iiX,iiY)
if not pLoopPlot.isNone():
if not pLoopPlot.isWater():
if not pLoopPlot.getTerrainType() == iSnow and not pLoopPlot.getTerrainType() == iGlacier:
pLoopPlot.setTerrainType(iSnow)
if pLoopPlot.getImprovementType() == iSmoke:
pLoopPlot.setImprovementType(-1)
if pLoopPlot.getImprovementType() == iNodeFire:
pLoopPlot.setImprovementType(iNodeIce)
if pPlot.getBonusType(-1) == iBonusFire:
pPlot.setBonusType(iBonusIce)
iFeature = pLoopPlot.getFeatureType()
if iFeature == iForest:
pLoopPlot.setFeatureType(iForest, 2)
if iFeature == iJungle:
pLoopPlot.setFeatureType(iForest, 2)
if iFeature == iFlames:
pLoopPlot.setFeatureType(-1, -1)
if iFeature == iFloodPlains:
pLoopPlot.setFeatureType(-1, -1)
if iFeature == iScrub:
pLoopPlot.setFeatureType(-1, -1)
- Edit: With Cassiel murdered at Auric's hands, the remaining Grigori have rallied behind Minister Koun to join the forces seeking to prevent a 2nd Age of Ice. I was surprised as any when Koun suddenly converted to the White Hand. Note that this is in a mod where Cassiel lacks the Agnostic trait, and some other mechanism prevents the Grigori from going religious. Any idea why this might have happened? Or are the Grigori now Ice-Worshippers in name only, unable to receive any of the benefits?
Cheers!
Cassiel is prevented from adopting a religion because he has a -100 religion weight modifier towards every religion. The Grigori civilization also has all the religion founding techs, all religious buildings except the holy shrines, and all of the religious units except for the Luonnotar disabled in its CIV4CivilizationInfos.xml defines.
Grigori leader that follows the White Hand wouldn't really receive any benefits, but would still become forced vassals of Auric Ulvin once he completes The Draw.
Koun does have a -100 religion weight modifier to The White Hand (all leaders but those of the Illian and Doviello civilizations do), which
should stop him from ever adopting it.
Are you using the Random Personalities game option? If so, he could have been set to have an Illian or Doviello leader's personality, including the religion preferences.
Was Koun generated through a revolution? The revolution code currently assigns a state religion to players it generates, and does not take religion weight modifiers into account. I've been trying to fix that, but without much luck so far. I just tried a new approach which I think will work better, but have not tested it yet. I mentioned the issue to Tholal and he agreed to change the code himself though, so if I cannot figure how to stop rebel civs from taking a blocked religion on my own I should be fine once I merge my modmod with the next release of More Naval AI.
- AI units with the AI_ CITYDEFENSE script will still conjure forth permanent summons, correct? So an Illian Barnaxus controlled by the AI would sit safe and sound in the capitol while cranking out Ice Golems that would rush forth?
I'm not really sure. AI questions should be directed towards Tholal.
I would guess this is the case though. Acheron has UNITAI_CITY_DEFENSE by default, and it my modmod he summons plenty of Fireballs with his Breath Fire ability. I don't imagine that permanent summons like Ice Golems would be treated much differently.