• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

MNAI-U: unofficial build & bugfixes

The thought just came to mind that it might be interesting to let merchant ships hurry production (like lesser Great Engineers, or Soldiers of Kilmorph) or add culture (like lesser Great Bards, or basic disciples), in which case I'd also want the Hurry and Great Works mission to also unload rather than kill their cargo. I cannot currently think of a scenario when I might want a unit with cargo to be sacrificed for a golden age or a technology, but you might as well make those missions unload cargo before killing the unit too if the code is simple enough.
These will all be fixed in the next version.

I think caravels are also not allowed to enter cities in BtS (except with open borders).

Maybe it would be better to exclude ships that are currently carrying cargo, or which have cargo that is not also bRivalTerritory?
Something like this is probably best, so the cargo units cannot cast spells, for example. But I'll tackle that after the next release.
 
I originally used bInvisible, but when I noticed the unit was still not visible to units with Perfect Sight I changed it to Stealth+Hidden instead.
I personally just gave hawks a starting promotion of perfect sight so that that promotion was useful in a way that wouldn't create a need for a lot more defensive units scattered around just for perfect sight. That said I do believe that perfect sight on a hawk is too early in the game and have plans on creating a hawk v2 for the hawk to upgrade into that has the perfect sight promotion instead.
 
... have plans on creating a hawk v2 for the hawk to upgrade into that has the perfect sight promotion instead.
How odd. For some reason I remember there being a racial variant for the hawk unit. A crow or something? But I don't see any reference to it now, either in the manual or the civilopedia. My brain is whack.
Anyway, your comment got me thinking about a hawk upgrade. The first thing that came to mind was a firebird (another name for a phoenix, but somehow sounds less powerful/mythical). You (probably) wouldn't want anything that would imply that the unit has combat abilities. On the other hand, FfH2 has never had any aerial units which could, for example, defend cities and shoot down other aerial units that are attempting to do recon. I suppose it's worth considering making that an option for your "hawk v2".
Just a thought.
 
How odd. For some reason I remember there being a racial variant for the hawk unit. A crow or something? But I don't see any reference to it now, either in the manual or the civilopedia. My brain is whack.

I do know the Lanun have parrots as a hawk model swap. Maybe the Sheaim have the crows, or the Sidar? I don't know, you need to rummage through the civs and see which one may have a crow as a hawk model swap.
 
New release: mnai-2.8.0u. Not compatible with 2.8-beta2u savegames.
Thanks to all bug reporters and to MagisterCultuum for code contributions.

Download
Please extract into "Mods/Fall from Heaven 2" (not into the Assets folder!)

This release contains many small fixes and code cleanup. See the the second post of this thread for a full changelog.

The release (non-assert) DLL is now compiled with whole program optimization, boosting speed significantly. Thanks to @devolution for pointing this out in the AdvCiv thread.

Information for Modder(s): I haven't changed Spell prereq system as announced earlier yet. canCast() now considers PromotionImmune, but I cannot guarantee that enabled spells really do something, as there might be further unfixed cases like that. CvUnit now has an exposed function isPromotionImmune(PromotionTypes); note, however, that spells also (still) consider UnitCombats when applying promotions.

I expect development will be much slower for the next 1-2 months, but I'll note your bug reports anyway, of course.
 
Last edited:
installed extramod version . every unit has "can nuke enemy lands" tag and nuke "teleporting" option.
 
I'm seeing something (since the latest patch) I don't remember ever seeing before. Can you think of any reason I would have Mistforms spawning near my lands starting at around the 50th turn? I don't know if they all spawned at once or one by one, but my units were only attacked by them one by one. Once mine and my neighbor's cultural borders filled in the space there (by around turn 100), the attacks seem to have stopped, but I haven't seen anything or any units that might have spawned them.
 
With the new DLL and my latest modmod release I am still getting these asserts:
Spoiler :
Code:
Assert Failed

File:  CyGlobalContext.cpp
Line:  70
Expression:  idx>=0
Message:  

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

File:  CvArtFileMgr.cpp
Line:  182
Expression:  false
Message:  get##name##ArtInfo:  was not found

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

File:  CvCity.cpp
Line:  7751
Expression:  getBonusGoodHealth() >= 0
Message:  

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

File:  CvCity.cpp
Line:  7753
Expression:  getBonusGoodHealth() >= 0
Message:  getBonusGoodHealth is expected to be >= 0

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

File:  CvUnit.cpp
Line:  12790
Expression:  getMoves() >= 0
Message:  

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

File:  CvCity.cpp
Line:  8326
Expression:  getBonusGoodHappiness() >= 0
Message:  

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

File:  z:\repos\mnai_unofficial\cvgamecoredll\CvPlayerAI.h
Line:  25
Expression:  ePlayer != NO_PLAYER
Message:  Player is not assigned a valid value

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

File:  CvCity.cpp
Line:  8338
Expression:  getBonusBadHappiness() <= 0
Message:  

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

File:  CvInfos.cpp
Line:  2666
Expression:  i > -1
Message:  Index out of bounds

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

File:  CvPlot.cpp
Line:  8638
Expression:  getStolenVisibilityCount(eTeam) >= 0
Message:  

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

File:  z:\repos\mnai_unofficial\cvgamecoredll\CvPlayerAI.h
Line:  25
Expression:  ePlayer != NO_PLAYER
Message:  Player is not assigned a valid value

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

File:  CvInitCore.cpp
Line:  1621
Expression:  eID >= 0
Message:  Index in CvInitCore::getCiv expected to be >= 0

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

Assert Failed

File:  CvPlayerAI.cpp
Line:  22762
Expression:  pPlot->getWorkingCity()->getOwner() == getID()
Message:  Event creates a boni for another player?

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

File:  CvUnitAI.cpp
Line:  12729
Expression:  getDomainType() == DOMAIN_LAND
Message:  

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

I'm seeing something (since the latest patch) I don't remember ever seeing before. Can you think of any reason I would have Mistforms spawning near my lands starting at around the 50th turn? I don't know if they all spawned at once or one by one, but my units were only attacked by them one by one. Once mine and my neighbor's cultural borders filled in the space there (by around turn 100), the attacks seem to have stopped, but I haven't seen anything or any units that might have spawned them.

Are there any tiles nearby that have Smoke? It could come from the Fire 1 spell or events like the Volcano. Smoke of course can spread from the original tile through forests etc.

There is an event (which I believe can be recurring) which (even in vanilla FfH2) can cause Mistforms to spawn from Smoke.

It seems plausible that removing a bunch of events that make no sense might have made other events (like the one spawning Mistforms from Smoke) more common.

Mistforms are of course also a possible result of lair exploration.
 
Are there any tiles nearby that have Smoke? It could come from the Fire 1 spell or events like the Volcano. Smoke of course can spread from the original tile through forests etc.

There is an event (which I believe can be recurring) which (even in vanilla FfH2) can cause Mistforms to spawn from Smoke.

It seems plausible that removing a bunch of events that make no sense might have made other events (like the one spawning Mistforms from Smoke) more common.

Mistforms are of course also a possible result of lair exploration.
Nope, no smoke. (Also, I've never seen a Mistform spawn from smoke, but maybe I've just been lucky.) It seems like a lot of Mistforms to have spawned (with a named mob) from a dungeon or other lair, but I can't rule it out. It could have been two lairs that coincidentally both spawned Mistforms. *shrug*
 
Did you have this problem in multiple games? Both the Mistform spawning event and exploration result was there before, and should not be more likely now. I didn't remove any other events.

Tholal made Mistforms start as UNITAI_ANIMAL, which means they don't enter cultural borders, to mitigate the problem of them killing off civs. I'm reluctant to change anything regarding balance, but I might make an exception for overpowered exploration result spawns and events like this. In ExtraModMod, I made them require a certain technology and/or unable to come near players' starting points. The former would be relatively easy to do in MNAI, too.
 
I'm seeing something (since the latest patch) I don't remember ever seeing before. Can you think of any reason I would have Mistforms spawning near my lands starting at around the 50th turn? I don't know if they all spawned at once or one by one, but my units were only attacked by them one by one. Once mine and my neighbor's cultural borders filled in the space there (by around turn 100), the attacks seem to have stopped, but I haven't seen anything or any units that might have spawned them.
That is why I made every explore lair and rob graveyard spell require you to have at least 3 cities before you are allowed to cast it. Too many barbarian doom stacks before I had anything better than warriors.
Did you have this problem in multiple games? Both the Mistform spawning event and exploration result was there before, and should not be more likely now. I didn't remove any other events.

Tholal made Mistforms start as UNITAI_ANIMAL, which means they don't enter cultural borders, to mitigate the problem of them killing off civs. I'm reluctant to change anything regarding balance, but I might make an exception for overpowered exploration result spawns and events like this. In ExtraModMod, I made them require a certain technology and/or unable to come near players' starting points. The former would be relatively easy to do in MNAI, too.
So I guess I can't swear to it but I really want to say that I've seen barbarian mistforms enter cultural borders but since I changed explore lair a couple years ago I just can't say for certain anymore.
 
Last edited:
Did you have this problem in multiple games?
This is the first game I've started since the last patch. I'll keep you informed.

So I guess I can't swear to it but I really want to say that I've seen barbarian mistforms enter cultural borders...
These ones definitely respected my borders. Otherwise that game'd be long over by now.
 
Could you let promotions change a unit's change of miscasting?

The miscasting mechanic does not really do anything now, but I am thinking of using it a lot in the next update.

edit: When I added some <PyMiscast> tags to some spells and gave Adepts <iMiscastChance>100</iMiscastChance> as a way to test them, I found these errors when their spells failed.
Code:
Traceback (most recent call last):

  File "CvSpellInterface", line 72, in miscast

AttributeError: 'CvSpellInfo' object has no attribute 'getPyMiscast'
ERR: Python function miscast failed, module CvSpellInterface

The code in question is this
Code:
def miscast(argsList):
   pCaster, eSpell = argsList
   spell = gc.getSpellInfo(eSpell)
   eval(spell.getPyMiscast())
I don't think I changed anything about it. It is possible Kael or Tholal wrote spell.getPyMiscast() but forgot to expose getPyMiscast() and ever noticed it since no spells actually used the tag?

Could you make sure it is exposed to python?

While at it, could you expose functions to check all the other tags?

I am thinking of simplifying the various helpShowSummonDetails tags as I found that gc.getSpellInfo(eSpell).getCreateUnitType() is exposed, but it seems I may still pave to pass a number of untis as gc.getSpellInfo(eSpell).getCreateUnitNum() is not exposed.
 
Last edited:
There is an event (which I believe can be recurring) which (even in vanilla FfH2) can cause Mistforms to spawn from Smoke.

It seems plausible that removing a bunch of events that make no sense might have made other events (like the one spawning Mistforms from Smoke) more common.
This explanation just became more plausible. I just got the smoke-mistform event in that same game, and it's only about turn 150. I've only ever had the smoke-mistform event once or twice before in any other playthrough. Granted, I never saw any smoke around the time of those first mistform attacks, but those mistforms prevented me from exploring the area they seemed to have spawned from for at least 20 turns. Oh, and I do have the map option on that increases events, so there's that. Or maybe I'm just having the weirdest string of luck.
 
That is why I made every explore lair and rob graveyard spell require you to have at least 3 cities before you are allowed to cast it. Too many barbarian doom stacks before I had anything better than warriors.
This seems generally better than just preventing strong spawns early on, as you cannot just clear lairs early without danger. However I'm not sure I like the 3 cities requirement as such. BTW, I think the strongest a graveyard can spawn is a spectre, so there's probably no need to change that.
EDIT: A distinction between epic and non-epic lairs might be good.
EDIT2: This seems interesting.

Could you let promotions change a unit's change of miscasting?
Yes, but this requires savegame-breaking changes (if done properly), so it might not make it into the next release.

Could you make sure it is exposed to python?

While at it, could you expose functions to check all the other tags?

I am thinking of simplifying the various helpShowSummonDetails tags as I found that gc.getSpellInfo(eSpell).getCreateUnitType() is exposed, but it seems I may still pave to pass a number of untis as gc.getSpellInfo(eSpell).getCreateUnitNum() is not exposed.
Yes, I'll expose them. It seems I should check out your helpShowSummonDetails and maybe include it in MNAI-U if it does what the name suggests. :)
 
Last edited:
You could look at the code in my last release, but the simplified version where I don't have to pass it a string to tell the spell what unit does like this:
In CvSpellInterface.py
Code:
def helpShowSummonDetails(lpUnits, eSpell, iNum = 1):
   szBuffer = ''

   if eSpell != -1:
       iUnit = gc.getSpellInfo(eSpell).getCreateUnitType()
##       iNum = gc.getSpellInfo(eSpell).getCreateUnitNum()#This is not exposed yet

       if iUnit > -1:
           iSummons = 0
           iTwincast = gc.getInfoTypeForString('PROMOTION_TWINCAST')
           infoU = gc.getUnitInfo(iUnit)
           for pCaster in lpUnits:
               if pCaster.canCast(eSpell, True):
                   iSummons += iNum
                   if pCaster.isHasPromotion(iTwincast):
                       iSummons += iNum
                   lPerks = []
                   for iProm in cf.getSummonPerks(pCaster):
                       if not infoU.getFreePromotions(iProm):
                           lPerks.append(iProm)
                   iCount = len(lPerks)
                   if iCount > 0:
                       szBuffer += '\n' + CyTranslator().getText("TXT_KEY_UNIT_STARTS_WITH", ())
                       if iCount == 1:
                           sList = gc.getPromotionInfo(lPerks.pop(0)).getDescription()
                       else:
                           sList = ''
                           while len(lPerks) > 0:
                               sList += gc.getPromotionInfo(lPerks.pop(0)).getDescription()
                               if len(lPerks) > 0:
                                   if len(lPerks) == 1:
                                       sList += " and "
                                   else:
                                       sList += ", "
                       szBuffer += sList
           sHelp = helpUnitHelp(iUnit)
           if iSummons == 1:
               sHelp = CyTranslator().getText("TXT_KEY_SPELL_SUMMON_UNIT", (sHelp,))
           else:
               sHelp = CyTranslator().getText("TXT_KEY_SPELL_SUMMON_UNIT_MULTIPLE", (iSummons, sHelp,))
               iStop = sHelp.rfind("(s).")#I don't want to include the "(s)."
               if iStop != -1:
                   sHelp = sHelp[:iStop]
           szBuffer = '\n' + sHelp + szBuffer
   return szBuffer
In CustomFunctions.py
Code:
   def getSummonPerks(self, pSummoner):
       lPerks = []
       for iProm in xrange(gc.getNumPromotionInfos()):
           if pSummoner.isHasPromotion(iProm):
               iPerk = gc.getPromotionInfo(iProm).getPromotionSummonPerk()
               if iPerk != -1:
                   lPerks.append(iPerk)
       return lPerks
(I should probably check the caster's promotions for one with bTwincast instead of just checking for Twincast, but without any more promotions using that tag this was easier.)
 
This seems generally better than just preventing strong spawns early on, as you cannot just clear lairs early without danger. However I'm not sure I like the 3 cities requirement as such. BTW, I think the strongest a graveyard can spawn is a spectre, so there's probably no need to change that.
EDIT: A distinction between epic and non-epic lairs might be good.
IMO barbarian technology would be a better requirement since that is based on the average civilization's technology but city count was a quick and dirty way for me to implement it especially since I also didn't know what technologies I wanted to allow them to work. I've never taken the time to figure out just what triggers epic and non-epic lairs but that would be really nice to know in game. Also I've lost a couple cities to spectre's fear early game. Having no counter to fear for quite some time makes them a pretty strong unit early game.
EDIT2: This seems interesting.
I like the clearing close stuff thing in the first few turns but IMO it should also toss up a count down timer like universal peace does at the beginning. I also think Guardians of Pristin Pass should not be spawnable in the starting area. I also blocked the ability to explore lairs if it was inside someone else's cultural borders mostly because I sometimes like to use them for experience fodder and friendly units were destroying them in my own lands. That is the reason that Tholal changed the dll to no longer have lairs auto explored when npc's walk on them because when I made that change I found out it wasn't working like I wanted.
 
Last edited:
Could you make it so that barbarian units generated from Goodies (like GOODY_GRAVE_SKELETONS) can be given a free promotion? (I am mostly thinking of making bad lair/graveyard results start with Hidden Nationality so that Barbarian trait leaders are not totally immune from bad results.)


Could you let specific units in their xml defines be given immunity to certain promotions, separate from what their promotions might block?

Could you give unit types combat bonuses against certain promotions, and promotions combat bonuses against certain units or unitcombats?

Could you teach the AI to understand that founding cities is disabled on some plots, and that they should move their settlers to plots where founding is not disabled rather than just waiting around doing nothing?

Can you stop barbarian cities or advanced start cities from being placed on found disabled tiles?

Could you make regenerating a map clear the found disabled status? (In my modmod I used pPlot.setFoundDisabled(True) to stop settlers from settling too close to Letum Frigus, as the White Hand ritual can turn that into a city, but found that regenerating the map would result in the area where Letum Frigus used to exist before regeneration being disabled for city founding for no apparent reason.)
 
Could you make it so that barbarian units generated from Goodies (like GOODY_GRAVE_SKELETONS) can be given a free promotion? (I am mostly thinking of making bad lair/graveyard results start with Hidden Nationality so that Barbarian trait leaders are not totally immune from bad results.)
Yes. I might some day port the XML-based unit spawning system from Extramodmod, but not in the near future.

Could you let specific units in their xml defines be given immunity to certain promotions, separate from what their promotions might block?
Is this really necessary? I think currently something like immunity to disease is handled just fine as a promotion that some units might start with.

Could you give unit types combat bonuses against certain promotions, and promotions combat bonuses against certain units or unitcombats?
Yes.

Can you stop barbarian cities or advanced start cities from being placed on found disabled tiles?

Could you make regenerating a map clear the found disabled status? (In my modmod I used pPlot.setFoundDisabled(True) to stop settlers from settling too close to Letum Frigus, as the White Hand ritual can turn that into a city, but found that regenerating the map would result in the area where Letum Frigus used to exist before regeneration being disabled for city founding for no apparent reason.)
That should be possible, although I never heard of FoundDisabled before, to be honest.
 
Back
Top Bottom