MNAI-U: unofficial build & bugfixes

I just had a weird issue in my modmod where the new Brotherhood of Wardens religion was being spread to every city of every player every turn.

When I closed the game and loaded a save, this issue did not continue.

(I recall one or two previous games where one of my new religions randomly appeared in my capital after the first turn. I never noticed it being spread to every other city then, but I probably did not keep playing long enough to build a second city or explore rival territory before saving and reloading anyway.)

My first guess was that this might have been caused by one of those memory issues causing the game to misread BUILDING_SHRINE_OF_SIRONA in the conditional statement I used to spread this religion to any city with the Shrine of Sirona. (This is a workaround I added to make up for the <ReligionChange> tags not working in Advanced Start. I was not playing an advanced start game at this point.)

It would make more sense for this behavior to occur if it cannot find BUILDING_SHRINE_OF_SIRONA and is instead spreading the religion after checking if pCity.getNumBuilding(-1) > 0:

If this was the case though, I would have expected to see an Assert upon loading and then have the Shrine of Sirona itself not to show up in the pedia, on the tech tree, or be buildable. I saw it there, and constructed it, and used the Sirona's Touch ability without any issue.

Edit: I just realized I was not using the assert DLL, so not seeing the assert is not strange.

It is possible for a memory corruption issue to be effecting the Python but not the XML code?


-----

Do you have any ETA on the next update?

I was thinking I might release a minor update of my own pretty soon, but would rather include your fixes if it would be ready within a week or two.

What are the chances that you'd decide to go ahead and add religion based production modifiers for buildings in the next version? It is fine if you don't. I'm asking only because I'd rather not waste time manually documenting the many discounts I gave in CvGameUtils.py if I'd be able to switch those to XML and have it all documented automatically.
 
It is possible for a memory corruption issue to be effecting the Python but not the XML code?
In theory, memory corruption may affect everything or nothing. But you're explanation seems plausible.

Do you have any ETA on the next update?

I was thinking I might release a minor update of my own pretty soon, but would rather include your fixes if it would be ready within a week or two.

What are the chances that you'd decide to go ahead and add religion based production modifiers for buildings in the next version? It is fine if you don't. I'm asking only because I'd rather not waste time manually documenting the many discounts I gave in CvGameUtils.py if I'd be able to switch those to XML and have it all documented automatically.
I'll go over my TODO list this weekend and decide what I want to include in the next release. I will then post an estimate here and whether I'll implement the religion production modifiers. The earliest possible release date would be next weekend (i.e. in ca. 2 weeks)
 
Could you make CyGameTextMgr().getUnitHelp show the unit types religion type, so the player can more easily know if a unit they are adding to a city's production queue or summoning has a religion?

Could you make the unit mousover info a little more terse, so that the info won't so often take up more space than is available on the screen and cause important info like the units strength, damage types, movement, and full promotion list be cut off? Ideally I'd like to add an ability to scroll through the mousevers to view all the data. I'd settle for consolidating the multiple "Immune to the X Promotion" lines into one "Immune to the X, Y, & Z Promotions," as in my modmod there are a lot of promotions granting immunity to a lot of promotions and therefore long lists of promotions immunes are the most common cause of the really long mouseovers.
 
Could you make CyGameTextMgr().getUnitHelp show the unit types religion type, so the player can more easily know if a unit they are adding to a city's production queue or summoning has a religion?
Yes.

Could you make the unit mousover info a little more terse, so that the info won't so often take up more space than is available on the screen and cause important info like the units strength, damage types, movement, and full promotion list be cut off? Ideally I'd like to add an ability to scroll through the mousevers to view all the data. I'd settle for consolidating the multiple "Immune to the X Promotion" lines into one "Immune to the X, Y, & Z Promotions," as in my modmod there are a lot of promotions granting immunity to a lot of promotions and therefore long lists of promotions immunes are the most common cause of the really long mouseovers.
Consolidating the immunities makes sense. The general problem, however, is hard to solve - as far as I can tell, line wrapping makes it impossible to say how high the displayed help text will be. I'm thinking of adding a BUG option to let the player customize the level of detail and/or the number of units displayed by default, but the code that generates the help text looks quite complicated.
 
In the past, I've found that the list of units shown when mousing over a Stack of Doom was too tall to fit on the screen. The main issue being that only some of the many, many precisely identical units in the stack were consolidated into a single line. In order to test whether that was still the case, I decided to create a stack of Barbarian Axemen. I opened WorldBuilder, selected the relevant options, and then clicked the left mouse button without mercy.

See attached image for results. The good news is that the list fits on the screen. Perhaps that's been fixed. The bad news is that getting an exact count of the Axemen in that stack from that list requires a fair bit of actual counting. In this case, I can find out that there are 51 of them by consulting the Military Advisor. In a case where a player has visibility on multiple doomstacks, figuring out how many of what is in each could be a frankly unreasonable amount of work.

It seems obvious to me that there should just be one line for all 51 Axemen. Although at that point, I'd want it not to leave out info given in the individual list items (unit category and movement).

Also shown: Dwarven Vault status is a fair bit in the way of the Civilopedia button. It's still clickable, but rather less easily so than usual.
 

Attachments

  • poorly condensed list of units on mouseover.png
    poorly condensed list of units on mouseover.png
    2.8 MB · Views: 1,147
Perhaps that's been fixed.
No, it's still a problem even in MNAI. Try units with many promotions and of many different types.

It seems obvious to me that there should just be one line for all 51 Axemen.
I somewhat disagree. Units in FfH can have a lot of individual promotions, so having as many as possible non-merged units seems good. Also, having a single non-merged unit might be nice as a reminder of their abilities (in your case, the only really new information is the unit combat type, but there are more complicated units than axemen, obviously). I'm not sure if the game does the latter right now, I think it doesn't.
Maybe a good compromise would be to indicate the number of non-merged units, too, like "Axeman (15+36)" in your case.

Also shown: Dwarven Vault status is a fair bit in the way of the Civilopedia button. It's still clickable, but rather less easily so than usual.
Noted, thanks.
 
I'd thought Ctrl+mouse wheel would scroll the list of units in a SoD, but I just tested it and it was only for one's own SoDs. Is there something that works for an enemy's SoD?
(Side note: If you've got a hidden unit on the same tile as the enemy's SoD, you can peruse all the enemy's units.)
 
Can you prevent the popup asking if you want to convert to a religion when it first spreads to your lands when it is not actually possible to convert to said religion due to a <ReligionWeightModifier> with <iWeightModifier>-100 ?
I checked this, <ReligionWeightModifier> only applies to AI, not to human players (in MNAI at least). This makes sense, actually.
I could add a <bCannotAdopt> tag for religions, or a python callback if you need more complex behavior.

I'd thought Ctrl+mouse wheel would scroll the list of units in a SoD, but I just tested it and it was only for one's own SoDs. Is there something that works for an enemy's SoD?
(Side note: If you've got a hidden unit on the same tile as the enemy's SoD, you can peruse all the enemy's units.)
Yeah, somehow having buttons for the AI units (even if you don't have a unit on the same tile) would be nice. But I don't even know how this should work; just showing them when hovering any enemy unit would be very confusing, and maybe not even possible.
Using mouse wheel with the help text is a nice idea and seems possible, I'll look into that.
 
I checked this, <ReligionWeightModifier> only applies to AI, not to human players (in MNAI at least). This makes sense, actually.
I could add a <bCannotAdopt> tag for religions, or a python callback if you need more complex behavior.
I remember Kael stated in the past that a <ReligionWeightModifier> of -100 should make it impossible for any player, human or otherwise, to ever adopt the religion, while any value of -99 or more only effects the AI. He said the value changed how the game calculates the percent of influence the religion has in your lands such that a -100 value makes it equivalent to trying to adopt a religion that has no presence in any of your cities.


Could you just use the existing def canConvert in CvReligionScreen.py to block those popups?

I currently use python code under canConvert in CvReligionScreen.py to prevent any Calabim leader from adopting The Empyrean or anyone at war with Auric from adopting The White Hand.


Spoiler :

Code:
   def canConvert(self, iReligion):
       if not iReligion < gc.getNumReligionInfos():
           iReligion = -1
       pPlayer = gc.getPlayer(self.iActivePlayer)
       if iReligion == pPlayer.getStateReligion() or not pPlayer.canConvert(iReligion):
           return False
       if iReligion != -1:
           iLeader = pPlayer.getLeaderType()
           if gc.getLeaderHeadInfo(iLeader).getReligionWeightModifier(iReligion) < -99:
               return False
           iCiv = pPlayer.getCivilizationType()
           if iCiv == gc.getInfoTypeForString('CIVILIZATION_GRIGORI'):
               return False

           if iReligion > gc.getInfoTypeForString('RELIGION_MATRONAE'):
               return False

           elif iReligion == gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'):
               if iCiv == gc.getInfoTypeForString('CIVILIZATION_CALABIM') or iLeader in [gc.getInfoTypeForString('LEADER_ALEXIS'), gc.getInfoTypeForString('LEADER_FLAUROS'), gc.getInfoTypeForString('LEADER_MAHON')]:
                   return False

           if gc.getGame().getProjectCreatedCount(gc.getInfoTypeForString('PROJECT_THE_DRAW')) > 0:
               iAuricPlayer = cf.getLeader(gc.getInfoTypeForString('LEADER_AURIC'))
               if iAuricPlayer != -1:
                   pAuricPlayer = gc.getPlayer(iAuricPlayer)
                   if pAuricPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_AURIC')) > 0:
                       iAuricTeam = pAuricPlayer.getTeam()

                       if iReligion == gc.getInfoTypeForString('RELIGION_WHITE_HAND'):
                           eAuricTeam = gc.getTeam(iAuricTeam)
                           iTeam = pPlayer.getTeam()
                           if eAuricTeam.isAtWar(iTeam):
                               return False
       ##               elif not iCiv in [gc.getInfoTypeForString('CIVILIZATION_ILLIANS'), gc.getInfoTypeForString('CIVILIZATION_DOVIELLO')]:
       ##                   return False
                       elif gc.getTeam(pPlayer.getTeam()).isVassal(iAuricTeam) or iLeader in [gc.getInfoTypeForString('LEADER_AURIC'), gc.getInfoTypeForString('LEADER_ANAGANTIOS'), gc.getInfoTypeForString('LEADER_DUMANNIOS'), gc.getInfoTypeForString('LEADER_RIUROS')]:
                           return False

       return True


(Checking on that code, I see also included lines to prevent adopting a religion with a religion modifier les than -99, which I was thinking was not needed because I thought Kael handled that in C++. Maybe Tholal changed that a while back so I added the python and then forgot?)


I also added some code in onPlayerChangeStateReligion of CvEventManager.py which undoes changes in case you convert through the popup rather than using the religion screen where canConvert would already stop you.

Spoiler :

Code:
   def onPlayerChangeStateReligion(self, argsList):
   ## Platy Builder ##
       if CyGame().GetWorldBuilderMode() and not CvPlatyBuilderScreen.bPython: return
   ## Platy Builder ##
       'Player changes his state religion'
       iPlayer, iNewReligion, iOldReligion = argsList
       if iNewReligion != iOldReligion:
           pPlayer = gc.getPlayer(iPlayer)
           iTeam = pPlayer.getTeam()
           iLeader = pPlayer.getLeaderType()
           iCiv = pPlayer.getCivilizationType()

           iOrder = gc.getInfoTypeForString('RELIGION_THE_ORDER')
           iEmpyrean = gc.getInfoTypeForString('RELIGION_THE_EMPYREAN')
           iRunes = gc.getInfoTypeForString('RELIGION_RUNES_OF_KILMORPH')
           iLeaves = gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES')
           iOverlords = gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS')
           iEsus = gc.getInfoTypeForString('RELIGION_COUNCIL_OF_ESUS')
           iVeil = gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL')
           iDragonCult = gc.getInfoTypeForString('RELIGION_CULT_OF_THE_DRAGON')
           iHand = gc.getInfoTypeForString('RELIGION_WHITE_HAND')
           iOne = gc.getInfoTypeForString('RELIGION_CHILDREN_OF_THE_ONE')

           iCitadel = gc.getInfoTypeForString('IMPROVEMENT_CITADEL')
           iCitadelOfLight = gc.getInfoTypeForString('IMPROVEMENT_CITADEL_OF_LIGHT')
           iHellFire = gc.getInfoTypeForString('IMPROVEMENT_HELLFIRE')


           iAphoticThrone = gc.getInfoTypeForString('BUILDING_APHOTIC_THRONE')
           iAphoticThroneHostile = gc.getInfoTypeForString('BUILDING_APHOTIC_THRONE_HOSTILE')


           if iNewReligion != -1:
               if gc.getLeaderHeadInfo(iLeader).getReligionWeightModifier(iNewReligion) < -99:
                   pPlayer.setLastStateReligion(iOldReligion)
                   iNewReligion = iOldReligion
                   pPlayer.changeAnarchyTurns(-pPlayer.getAnarchyTurns())
               if iCiv == gc.getInfoTypeForString('CIVILIZATION_GRIGORI'):
                   pPlayer.setAlignment(gc.getInfoTypeForString('ALIGNMENT_NEUTRAL'))
                   pPlayer.setLastStateReligion(-1)
                   iNewReligion = -1
                   pPlayer.changeAnarchyTurns(-pPlayer.getAnarchyTurns())
               elif iNewReligion == iDragonCult:
                   if not pPlayer.isBarbarian():
                       pPlayer.setLastStateReligion(iOldReligion)
                       iNewReligion = iOldReligion
                       pPlayer.changeAnarchyTurns(-pPlayer.getAnarchyTurns())
               elif iNewReligion == iOne:
                   pPlayer.setLastStateReligion(iOldReligion)
                   iNewReligion = iOldReligion
                   pPlayer.changeAnarchyTurns(-1)
               elif iNewReligion == iEmpyrean:
                   if iCiv == gc.getInfoTypeForString('CIVILIZATION_CALABIM') or iLeader in [gc.getInfoTypeForString('LEADER_ALEXIS'), gc.getInfoTypeForString('LEADER_FLAUROS'), gc.getInfoTypeForString('LEADER_MAHON')]:
                       pPlayer.setLastStateReligion(iOldReligion)
                       iNewReligion = iOldReligion
                       pPlayer.changeAnarchyTurns(-pPlayer.getAnarchyTurns())

               if iNewReligion != iHand and iLeader in [gc.getInfoTypeForString('LEADER_AURIC'), gc.getInfoTypeForString('LEADER_ANAGANTIOS'), gc.getInfoTypeForString('LEADER_DUMANNIOS'), gc.getInfoTypeForString('LEADER_RIUROS')]:
                   pPlayer.setLastStateReligion(-1)
                   iNewReligion = -1

               if gc.getGame().getProjectCreatedCount(gc.getInfoTypeForString('PROJECT_THE_DRAW')) > 0:
                   iAuricPlayer = cf.getLeader(gc.getInfoTypeForString('LEADER_AURIC'))
                   if iAuricPlayer != -1:
                       pAuricPlayer = gc.getPlayer(iAuricPlayer)
                       if pAuricPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_AURIC')) > 0:
                           iAuricTeam = pAuricPlayer.getTeam()

                           if iNewReligion == iHand:
                               eAuricTeam = gc.getTeam(iAuricTeam)
                               iTeam = pPlayer.getTeam()
                               if eAuricTeam.isAtWar(iTeam):
                                   pPlayer.setLastStateReligion(iOldReligion)
                                   pPlayer.changeAnarchyTurns(-pPlayer.getAnarchyTurns())

                           elif gc.getTeam(pPlayer.getTeam()).isVassal(iAuricTeam):
                               pPlayer.setLastStateReligion(iHand)
                               iNewReligion = iHand


           if iNewReligion == iOrder:
               pPlayer.setAlignment(gc.getInfoTypeForString('ALIGNMENT_GOOD'))
           elif iNewReligion == iEmpyrean:
               for pPlot in PyPlayer(iPlayer).getPlotsWithImprovement(iCitadel):
                   pPlot.setImprovementType(iCitadelOfLight)
           elif iNewReligion == iVeil:
               pPlayer.setAlignment(gc.getInfoTypeForString('ALIGNMENT_EVIL'))

           if iNewReligion == iEsus or (pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_UNDERCOUNCIL')) and CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_ALLOW_APHOTIC_THRONES'))):
##               if pPlayer.countNumBuildings(iAphoticThroneHostile) > 0:
               if pPlayer.getBuildingClassCountPlusMaking(gc.getInfoTypeForString('BUILDINGCLASS_APHOTIC_THRONE_HOSTILE')) > 0:

                   (loopCity, iter) = pPlayer.firstCity(False)
                   while(loopCity):
                       if (not loopCity.isNone() and loopCity.getOwner() == iPlayer): #only valid cities
                           if loopCity.getNumBuilding(iAphoticThroneHostile):
                               loopCity.setNumRealBuilding(iAphoticThroneHostile, 0)
                               loopCity.setNumRealBuilding(iAphoticThrone, 1)
                           else:
                               loopCity.setBuildingProduction(iAphoticThrone, loopCity.getBuildingProduction(iAphoticThroneHostile))
                               loopCity.setBuildingProduction(iAphoticThroneHostile, 0)
                               if loopCity.getProductionBuilding () == iAphoticThroneHostile:
                                   loopCity.pushOrder(OrderTypes.ORDER_CONSTRUCT,iAphoticThrone,-1, False, True, False, True)


                       (loopCity, iter) = pPlayer.nextCity(iter, False)
                   (loopCity, iter) = pPlayer.firstCity(False)
##           elif pPlayer.countNumBuildings(iAphoticThrone) > 0:
           elif pPlayer.getBuildingClassCountPlusMaking(gc.getInfoTypeForString('BUILDINGCLASS_APHOTIC_THRONE')) > 0:
               (loopCity, iter) = pPlayer.firstCity(False)
               while(loopCity):
                   if (not loopCity.isNone() and loopCity.getOwner() == iPlayer): #only valid cities
                       if loopCity.getNumBuilding(iAphoticThrone):
                           loopCity.setNumRealBuilding(iAphoticThrone, 0)
                           loopCity.setNumRealBuilding(iAphoticThroneHostile, 1)
                       else:
                           loopCity.setBuildingProduction(iAphoticThroneHostile, loopCity.getBuildingProduction(iAphoticThrone))
                           loopCity.setBuildingProduction(iAphoticThrone, 0)
                           if loopCity.getProductionBuilding () == iAphoticThrone:
                               loopCity.pushOrder(OrderTypes.ORDER_CONSTRUCT,iAphoticThroneHostile,-1, False, True, False, True)
                   (loopCity, iter) = pPlayer.nextCity(iter, False)
               (loopCity, iter) = pPlayer.firstCity(False)




           if iOldReligion == iVeil and iCiv != gc.getInfoTypeForString('CIVILIZATION_INFERNAL'):
               if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_TACTICS):
                   for pPlot in PyPlayer(iPlayer).getPlotsWithImprovement(iHellFire):
                       pPlot.setOwner(gc.getBARBARIAN_PLAYER())



               lPacts = [   (gc.getInfoTypeForString('LEADER_HYBOREM'), gc.getInfoTypeForString('EVENT_SUMMON_HYBOREM')),
                           (gc.getInfoTypeForString('LEADER_JUDECCA'),gc.getInfoTypeForString('EVENT_SUMMON_JUDECCA')),
                           (gc.getInfoTypeForString('LEADER_LETHE'), gc.getInfoTypeForString('EVENT_SUMMON_LETHE')),
                           (gc.getInfoTypeForString('LEADER_MERESIN'), gc.getInfoTypeForString('EVENT_SUMMON_MERESIN')),
                           (gc.getInfoTypeForString('LEADER_OUZZA'), gc.getInfoTypeForString('EVENT_SUMMON_OUZZA')),
                           (gc.getInfoTypeForString('LEADER_SALLOS'), gc.getInfoTypeForString('EVENT_SUMMON_SALLOS')),
                           (gc.getInfoTypeForString('LEADER_STATIUS'), gc.getInfoTypeForString('EVENT_SUMMON_STATIUS')),
                           ]

               for iDemon, iEvent in lPacts:
                   if pPlayer.getLeaderType() == iDemon:continue
                   if pPlayer.getEventOccured(iEvent):
                       pPlayer.resetEventOccured(iEvent)
                       if pPlayer.isHuman():
                           infoD = gc.getLeaderHeadInfo(iDemon)
                           cf.addPopup(CyTranslator().getText("TXT_KEY_POPUP_INFERNAL_PACT_BROKEN",(infoD.getDescription(), )), infoD.getButton())

                       iDemonPlayer = cf.getLeader(iDemon)
                       if iDemonPlayer != -1:
                           pDemonPlayer = gc.getPlayer(iDemonPlayer)
                           iDemonTeam = pDemonPlayer.getTeam()

                           pDemonPlayer.AI_changeAttitudeExtra(iPlayer,-12)
                           gc.getTeam(iDemonTeam).setHasPrepareWar(iTeam,True)



                       if not pPlayer.hasTrait( gc.getInfoTypeForString('TRAIT_BARBARIAN')):
                           bTeam = gc.getTeam(gc.getBARBARIAN_TEAM())
                           iTeam = pPlayer.getTeam()
                           if not bTeam.isAtWar(iTeam):
                               if bTeam.canDeclareWar(iTeam):
                                   bTeam.declareWar(iTeam, False, WarPlanTypes.WARPLAN_TOTAL)

                               if pPlayer.isHuman():
                                   cf.addPopup(CyTranslator().getText("TXT_KEY_POPUP_BARBARIAN_DECLARE_WAR",()), 'art/interface/popups/Barbarian.dds')

Yeah, somehow having buttons for the AI units (even if you don't have a unit on the same tile) would be nice. But I don't even know how this should work; just showing them when hovering any enemy unit would be very confusing, and maybe not even possible.
Using mouse wheel with the help text is a nice idea and seems possible, I'll look into that.


Using a mouse Scroll Wheel (or the Page Up/Page Down buttons) to scroll through help text while the cursor is hoverning over a uniti or spell is exactly what I really wanted, but assumed would be impossible as that is normally used for zoming in or out.

I never realized that Ctrl+Scroll Wheel did anything, but believe I will be using it a lot now.

That opens up the possibility of maybe using Alt+Scroll Wheel or Shift+Scroll Wheel for reading longer help texts.

It would be wonderful if you can manage it.
 
Last edited:
I remember Kael stated in the past that a <ReligionWeightModifier> of -100 should make it impossible for any player, human or otherwise, to ever adopt the religion, while any value of -99 or more only effects the AI. He said the value changed how the game calculates the percent of influence the religion has in your lands such that a -100 value makes it equivalent to trying to adopt a religion that has no presence in any of your cities.
This is not true in the current codebase. ReligionWeightModifier affects AI_techValue and AI_religionValue, and in CvPlayer::canDoReligion, we have
Spoiler :

Code:
//FfH Traits: Added by Kael 08/02/2007
   if (isAgnostic())
   {
       return false;
   }

   if (!isHuman())
   {
       if (GC.getLeaderHeadInfo(getPersonalityType()).getReligionWeightModifier(eReligion) <= -100)
       {
           return false;
       }
   }
//FfH: End Add


Could you just use the existing def canConvert in CvReligionScreen.py to block those popups?
No, not directly. Methods cannot be called from C++. I could, however, move that code into a callback function.
 
It is definitely different in MNI than vanilla FfH2 then.

The0.41o codebase says:
Code:
bool CvPlayer::canDoReligion(ReligionTypes eReligion) const
{
   if (GET_TEAM(getTeam()).getHasReligionCount(eReligion) == 0)
   {
       return false;
   }

//FfH Traits: Added by Kael 08/02/2007
    if (isAgnostic())
    {
        return false;
    }
    if (GC.getLeaderHeadInfo(getPersonalityType()).getReligionWeightModifier(eReligion) <= -100)
    {
        return false;
    }
//FfH: End Add
/*************************************************************************************************/
/**   BETTER AI (favorite Religions) Sephi                                                        **/
/**                                                                                               **/
/**                                                                                               **/
/*************************************************************************************************/
    if (!isHuman())
    {
        if (GC.getLeaderHeadInfo(getPersonalityType()).getReligionWeightModifier(eReligion) < 0)
        {
            return false;
        }
    }
/*************************************************************************************************/
/**   END                                                                                           **/
/*************************************************************************************************/

   return true;
}
 
I don't mind moving the code currently in CvReligionScreen.py's def canConvert(self, iReligion): to some other file, but I'd rather the callback not only apply to human players. I'd still want to be able to, e.g., block an AI from adopting The White Hand while at war with Auric Ulvin.
 
The thought just came to mind that it might be nice to have a parameter in the new callback to determine whether the player is in the process of negotiating a peace treaty. I generally would not a player to start worshiping Auric while waging war against him, but Auric would certainly like to make his enemies agree to start worshiping him as part of a peace treaty. That is not a super high priority though.
 
I just noticed a really odd bug. When my total gold supply went negative (due to a rival using the Embezzlement ability) it for some reason prevented any of my units from casting any spells or using any abilities of their own.
 
I believe that's what Cold-War Russians meant when they used to say, "We pretend to work and they pretend to pay us." :lol:
 
I just noticed a really odd bug. When my total gold supply went negative (due to a rival using the Embezzlement ability) it for some reason prevented any of my units from casting any spells or using any abilities of their own.
I haven't looked at the code yet, but it's probably a check like "total gold >= cost", where cost is 0 for most spells.
That would be easy to fix, but I'm not sure if it is a good idea to allow negative gold. There might be more stuff that goes wrong.
 
Can you make sure that an AI identifies other AIs by the leader name instead of only the civilization type in cases where multiple leaders of the same civilization are present in the game at the some time?
OKSleeper just complained about trade demands while all 7 demons lords were in his game, but it is an issue that had often annoyed me in the past as well.
--
Would it be possible to block units that have a religion from upgrading to unit types with a different religion as a <PrereqReligion> ?

I like letting my Wanderers upgrade to a wide variety of units, but I don't really want Tali's worshipers becoming UUs of other religions.

edit: I just realized this would also prevent me from letting Gaelan upgrade to his Burnt Priest form though. I guess I could always switch that to work through a spell, though it would be nice if a regular unit upgrade could have a python callback to block upgrades based on the upgrading unit's religion/promotions/alignment/etc.
---

I'm not sure I'd seen these two asserts before this week.
Code:
Assert Failed

File:  CvCityAI.cpp
Line:  8496
Expression:  iIndex >= 0
Message:  iIndex is expected to be non-negative (invalid Index)

----------------------------------------------------------

Assert Failed

File:  CvGlobals.cpp
Line:  1883
Expression:  eBuildNum < GC.getNumBuildInfos()
Message:
I had a caved game where those kept happening consistently, and about half the time the game would then immediately crash. I accidentaly deleted that save though, and have since made some changes that would break a save anyway.
 
Back
Top Bottom