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

MNAI-U: unofficial build & bugfixes

Discussion in 'More Naval AI Modmod' started by lfgr, May 15, 2019.

  1. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    I'll wait for future reports then.

    I don't know much about art, so I cannot help you with the golshan issue.

    I was replying to Calavente, who seemed to argue for not removing any default tags. For your solution my criticism would only apply to the top/bottom entry. I do not see that much of a difference between your and my solution, I think mine is a bit cleaner. Also, many text editors do not like to open a file twice, so with your solution you'd have to switch between the top and some other position in the file, as opposed to just switching between two files. The advantage of your solution is that new modders just have to find that one file, but that's what READMEs are for (or maybe I'll just refer to the example file in the header comment).
    By the way, if you only need to know the order or availability of tags, you can always just look into the Schema file. For me, the only reason to add an example entry would be to allow people to copy/paste stuff, thus making editing a bit faster.

    That sounds reasonable, I will do that.
     
  2. Calavente

    Calavente Richard's voice

    Joined:
    Jun 4, 2006
    Messages:
    2,788
    Location:
    France
    In fact I was arguing to keep a model in the file, at top or bottom, for new modders, but also for an easy access to references. It would also help limit errors : this tag works for the units but not the promotions / or for the buildings and not the spells ...etc.
    A readme would be more complicated IMO, but I see your point of 2 files. but then nothing blocks having both a full set IN the file and a full set in a readme.
    However the best improvement would be what you propose: remove the order ! (that one is really a ***** !)(but a full list somewhere would still be useful / needed)

    Are there "easy" ways to transfer tags from promotions/units/buildings to another file ? (or only dll ?)
    I remember that there are some effects that only work when applied through promotions and others units effects not applicable through promotions.
     
  3. omegaflames

    omegaflames Warlord

    Joined:
    Sep 21, 2012
    Messages:
    134
    As far as the default tag thing goes I think that removing tag entries that aren't needed/used in each unit's entry itself would make the files much easier to read but also having an example entry that lists all the tags in the correct order somewhere as well whether in the same file or a different one as long as it's easy to find. The easy to find part is key here especially new modders. I once assumed the schema served that purpose but I then noticed it didn't always line up with what was going in the xml files and things sometimes repeat themselves in it so I never really did figure out for sure what goes in what order or what the schema actually controls and always just winged it. Also I had to lol at you guys using professional python editors and me over here still using notepad++ only barely knowing what I'm doing in python to begin with, at least I give good bug reports!
     
    Tielby likes this.
  4. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    You'd need DLL work for that.

    Tag order is only controlled by the schema, the DLL does not care (or at least I never saw any code that suggested otherwise). Some Schema files missed declaring some tags properly, but I think I fixed that a few weeks ago.
     
  5. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    16,108
    Location:
    Kael's head
    If you could easily transfer tags from units to promotions or vice versa, I would have long ago been using <PyPerTurn> effects for units and <PythonPostCombatWon> and <PythonPostCombatLost tags> for promotions.

    Instead of the PythonPostCombat promotions I've been forced to use def onCombatResult(self, argsList): in CvEventManager.py

    What I'd really like though is a python call I could use when units withdraw from combat, instead of only when combat results in the death of one unit or another.

    In the short term though I think a higher priority would be a python function to check to see whether a unit is immune to a promotion, and changing the xml spells so that it won't think ineligible units are valid targets for promotion granting spells.
    ---


    Could you let promotions grant the ability to move through rival territory without open borders or right of passage agreements? I believe Tholal already let them allow units to move through limited borders, but ignoring open borders entirely would be more useful.

    I am mostly interested in letting Hidden or Invisible units ignore borders until they get caught, but then getting ejected or trapped if someone casts Revelation on them. If you prefer to make the <bInvisible> tag let units ignore borders I'd be fine with that. It might even be nicer if those units freedom of movement only applied when not within the line of sight of a unit able to see them while invisible. However, modders might also find a use for a separate tag that let units move through rival territory while fully visible.


    --

    I just fixed the setLevel issues as you recommended. Besides what you called out everything setting a unit's level took an unmodified level from another unit, so there should not be any way for it to be less than 1.

    ---

    While looking through the python files I noticed my CvRandomEventInterface.py still includes a lot of code from vanilla BtS events that I don't think make any sense with FfH2. Some of them reference things from the XML which are not found in any FfH2 modmods, like 'SPECIALBUILDING_CATHEDRAL', ,'SPECIALBUILDING_MONASTERY', 'UNITCLASS_SPEARMAN', 'CIVIC_EMANCIPATION', etc.

    Those are found in your version of CvRandomEventInterface.py too.

    If you are cleaning up files to remove extra tags, to reduce file size and make them easier to read, you should probably clean up such events too.

    ---
    I'm still getting these asserts:
    Spoiler :
    Code:
    Assert Failed
    
    File:  CvGame.cpp
    Line:  5803
    Expression:  getBuildingClassCreatedCount(eIndex) <= GC.getBuildingClassInfo(eIndex).getMaxGlobalInstances()
    Message:  Index is expected to be within maximum bounds (invalid Index)
    
    ----------------------------------------------------------
    Assert FailedAssert Failed
    
    File:  CyGlobalContext.cpp
    Line:  70
    Expression:  idx>=0
    Message:
    
    ----------------------------------------------------------
    
    
    File:  CvCity.cpp
    Line:  8326
    Expression:  getBonusGoodHappiness() >= 0
    Message:
    
    ----------------------------------------------------------
    Assert Failed
    Assert Failed
    
    File:  CvInfos.cpp
    Line:  2673
    Expression:  i > -1
    Message:  Index out of bounds
    
    ----------------------------------------------------------
    
    File:  CvCity.cpp
    Line:  8338
    Expression:  getBonusBadHappiness() <= 0
    Message:
    
    ----------------------------------------------------------
    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:  CvArtFileMgr.cpp
    Line:  182
    Expression:  false
    Message:  get##name##ArtInfo:  was not found
    
    ----------------------------------------------------------
    Assert Failed
    
    File:  CvUnitAI.cpp
    Line:  25485
    Expression:  false
    Message:
    
    ----------------------------------------------------------
    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 < ((50) + 1)
    Message:  Index in CvInitCore::getCiv expected to be < 51
    
    ----------------------------------------------------------
    
    
     
    Last edited: Jul 11, 2019
    Tielby likes this.
  6. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    Did you get all these asserts in MNAI-U or in MagisterModMod? I played through the scenario up to the Meshabber and didn't get any.

    @MagisterCultuum: You're suggestions seem reasonable. I will look into these and your earlier suggestions before the next release (and probably implement them if it isn't unreasonably complicated).
     
  7. thegreekweegee

    thegreekweegee Warlord

    Joined:
    Mar 20, 2013
    Messages:
    292
    MagisterModMod. I don't play MNAI-U. You tried playing through the scenario with MNAI-U?
     
  8. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    Yes. You reported your issue here in the MNAI-U thread. When you do that, please specify that it comes from MagisterModMod. :)
     
  9. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    16,108
    Location:
    Kael's head
    I just got a little alloyed that there was not a way to toggle pUnit.setIgnoreHide(bool) in worldbuilder, so I added that function to C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\Magister Modmod for FfH2\Assets\python\Screens\PlatyBuilder\WBUnitScreen.py

    I tried to similarly add the ability to toggle pUnit.setBlockading(bool) , but found that it does not work because pUnit.isBlockading(bool) is not exposed to python.

    Would you mind exposing that?
     
  10. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    Done.
     
  11. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    It seems the current situation with units affected by Promotion-granting spells is a bit weird. Currently, a spell adding promotion P to units only does that if the target unit does not have P and has a UnitCombat allowed by P (and also, P can never be applied to a unit immune to P). I'd like to change those requirements to the canAcquirePromotion() function to streamline things (for example, PromotionCombatApply uses canAcquirePromotion()). That would add the following requirements to add promotion P to unit U: U must have all PrereqPromotions of P, P must not be a race nor an equipment promotion, U must have the prerequisite level and religion of P, U must be alive if P requires it, the owner of U must have the proper Bonus, Tech and state religion required by P. (see also canAcquirePromotion() in the DLL source)
    To me it doesn't seem like this would cause any problems, but I figured I'd ask you anyway because you have more experience with spells and do crazy stuff in MagisterModMod. Having it streamlined like this would allow for easier fixes for your problems.
    An alternative would be to allow more or less every promotion to be applied and specify all requirements in the spells via my upcoming prereq system.
     
  12. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    16,108
    Location:
    Kael's head
    My first thought is that using canAcquirePromotion() would probably break all of the promotion-granting spells.

    Wouldn't it mean that spells could not be used to add promotions which cannot be gained though experience?

    I cannot off the top of my head think of any of the promotion granting spells that add promotions that normally can be gained through experience.

    Most if not all of them add Effects, i.e., promotions with either a TECH_NEVER or <MinLevel>-1 prereq tag.

    What use would the Courage or Shaddowwalk spells be if those were promotions units could normally gain without any arcane assistance?




    Also, there are spells intended to add equipment promotions. Most are picking up equipment from another unit, building, etc. Most have the bBuffCasterOnly tag which also lets the spell ignore the promotion's unitcombats and the units magic immunity.

    In my modmod however the Spellstaff promotion is a piece of equipment that Enchantment 3 can add to the caster and Enchantment Affinity + Channeling 3 can add to all arcane units in the stack.


    In addition to reforming spells spells so you cannot cast them when being immune to a promotion would make them have no effect, I think we really need to expose a python function to tell us whether a unit is immune to a promotion. It is essential for many PyHelp strings to be accurate and would be quite useful elsewhere too.
     
  13. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    The <MinLevel>-1</iMinLevel> check is done in canPromote(), which is used to check if a unit can purchase a promotion the normal way. TECH_NEVER is not used for promotions in MNAI (why would it, when you can do the same with MinLevel).

    But the equipment promotions is a legitimate concern. I think I can move that check from canAcquirePromotion() to canPromote(), though.
    Another thing I missed is that spells should be applied to units with no unitcombat, but these units cannot purchase any promotions.

    Exactly. I will probably expose CvUnit::isPromotionImmune(), but that will only tell you what the PromotionImmune XML tags say. That means, if isPromotionImmune() says false, it doesn't necessarily mean any given game mechanic will apply that promotion to the unit. For example, PromotionCombatApply will currently use canAcquirePromotion() and not apply any equipment promotion, or any promotion with a tech the target unit's owner doesn't have, including TECH_NEVER. Spells, on the other hand, will apply a promotion if the target unit is not immune and has the right unitcombat (or has no unitcombat). You'd have to check both these things in python.
    What I want to do is to unify all that so you only ever have to check canAcquirePromotion() to see if a promotion will be applied by one of these mechanics. Without going into details, this would also simplify the C++ code necessary for disabling spells when they would have no effect.
     
  14. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    I found another inconsistency: The spells with <bBuffCasterOnly>1</bBuffCasterOnly> apply promotions without checking for unitcombat (only for immunity). So I think the cleanest solution would actually be to only check for immunity when applying promotions to target units (and whether the promotion is already present, of course). For promotions that used to specify only specific unitcombats, the spell will need to specify that. I think this is actually a good thing, as the spell can then list these requirements itself, rather than people having to look up the promotion.
    Some unitcombat requirements seem actually unintentional. Courage, for example, is not applied to beast units, but to animal units. Sounds like an oversight, maybe when the beast unitcombat were added?

    Thoughts/complains? I'll need to add/adjust the new prereq system beforehand, so if you have comments on that, please state them in the next few days, ideally.
     
  15. Tielby

    Tielby Prince

    Joined:
    Sep 23, 2007
    Messages:
    313
    Location:
    The sacred and free citadel of mind
    How soon might the next non-beta (i.e. post-savegame-breaking) version be out. I don't want to get too invested in my current game if I'm just going to break it soon. Doing my best to keep up with the latest versions, so I can try to helpfully playtest what y'all are doing. Thanks for doing it!
     
  16. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    You're welcome, thanks for playtesting. I plan to release 2.8.0u this weekend, which is supposed to last for some time.
     
    Tielby likes this.
  17. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    16,108
    Location:
    Kael's head
    I just added adding a couple of new naval units (Merchantman and Smuggler Ship) in my modmod which can conduct trade missions like Great Merchants can (although not quite as profitable).

    I don't like how conducting the trade mission kills not only the unit but also any cargo it is carrying though.

    Could you make the trade mission unload any cargo before killing the unit, just like Tholal long ago made units unload their cargo just before their duration expires?

    (By the way, do immortal units still die permanently when in a ship that is destroyed? I really wish they wouldn't.)


    The Smuggler Ship I added has <bRivalTerritory>1</bRivalTerritory>, but I found that the ship still cannot enter a city to conduct a trade mission unless I have an Open Borders Agreement. (Not even a Right of Passage Agreement helps.) Could you change that in the next release too?
     
  18. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    721
    This will be fixed in the next version.

    Caravel uses bRivalTerritory, and judging from the source code, it is intended that they can't enter cities. I'll have to investigate why. Could you post the whole XML code for smuggler ship? In particular, I would be interested whether it is invisible.
     
  19. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    16,108
    Location:
    Kael's head
    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.


    If I had to guess, I'd say the reason Caravels were not allowed to enter cities without open borders was to stop them from dropping a unit like a Nightwatch there. Maybe it would be better to exclude ships that are currently carrying cargo, or which have cargo that is not also bRivalTerritory?


    Right now the Smuggler xml defines is this
    Spoiler :
    Code:
    
           <UnitInfo>
               <Class>UNITCLASS_SMUGGLER</Class>
               <Type>UNIT_SMUGGLER</Type>
               <Combat>UNITCOMBAT_NAVAL</Combat>
               <Domain>DOMAIN_SEA</Domain>
               <DefaultUnitAI>UNITAI_MERCHANT</DefaultUnitAI>
               <Description>TXT_KEY_UNIT_SMUGGLER</Description>
               <Civilopedia>TXT_KEY_UNIT_PLACEHOLDER_PEDIA</Civilopedia>
               <Advisor>ADVISOR_ECONOMY</Advisor>
               <bMilitarySupport>0</bMilitarySupport>
               <bMilitaryProduction>0</bMilitaryProduction>
               <bPillage>0</bPillage>
               <bMechanized>1</bMechanized>
               <bRenderBelowWater>1</bRenderBelowWater>
               <bMilitaryTrade>1</bMilitaryTrade>
               <bOnlyDefensive>1</bOnlyDefensive>
               <bRivalTerritory>1</bRivalTerritory>
               <bSabotage>0</bSabotage>
               <bDestroy>1</bDestroy>
               <bStealPlans>1</bStealPlans>
               <bInvestigate>1</bInvestigate>
               <bInvisible>0</bInvisible>
               <UnitClassUpgrades>
                   <UnitClassUpgrade>
                       <UnitClassUpgradeType>UNITCLASS_FIRE_SHIP</UnitClassUpgradeType>
                       <bUnitClassUpgrade>1</bUnitClassUpgrade>
                   </UnitClassUpgrade>
               </UnitClassUpgrades>
               <UnitAIs>
                   <UnitAI>
                       <UnitAIType>UNITAI_MERCHANT</UnitAIType>
                       <bUnitAI>1</bUnitAI>
                   </UnitAI>
                   <UnitAI>
                       <UnitAIType>UNITAI_EXPLORE_SEA</UnitAIType>
                       <bUnitAI>1</bUnitAI>
                   </UnitAI>
                   <UnitAI>
                       <UnitAIType>UNITAI_SETTLER_SEA</UnitAIType>
                       <bUnitAI>1</bUnitAI>
                   </UnitAI>
               </UnitAIs>
               <Buildings>
                   <Building>
                       <BuildingType>BUILDING_SMUGGLERS_PORT</BuildingType>
                       <bBuilding>1</bBuilding>
                   </Building>
               </Buildings>
               <PrereqTech>TECH_TRADE</PrereqTech>
               <TechTypes>
                   <PrereqTech>TECH_SAILING</PrereqTech>
                   <PrereqTech>TECH_CURRENCY</PrereqTech>
               </TechTypes>
               <iCost>300</iCost>
               <iAdvancedStartCost>100</iAdvancedStartCost>
               <iMinAreaSize>20</iMinAreaSize>
               <iMoves>4</iMoves>
               <TerrainImpassables>
                   <TerrainImpassable>
                       <TerrainType>TERRAIN_OCEAN</TerrainType>
                       <bTerrainImpassable>1</bTerrainImpassable>
                   </TerrainImpassable>
               </TerrainImpassables>
               <TerrainPassableTechs>
                   <TerrainPassableTech>
                       <TerrainType>TERRAIN_OCEAN</TerrainType>
                       <PassableTech>TECH_ASTRONOMY</PassableTech>
                   </TerrainPassableTech>
               </TerrainPassableTechs>
               <iCombat>4</iCombat>
               <iBaseTrade>100</iBaseTrade>
               <iTradeMultiplier>200</iTradeMultiplier>
               <iXPValueAttack>8</iXPValueAttack>
               <iXPValueDefense>4</iXPValueDefense>
               <iBombardRate>0</iBombardRate>
               <iWithdrawalProb>40</iWithdrawalProb>
               <DomainCargo>DOMAIN_LAND</DomainCargo>
               <iCargo>0</iCargo>
               <iAsset>9</iAsset>
               <iPower>12</iPower>
               <UnitMeshGroups>
               <iGroupSize>1</iGroupSize>
               <fMaxSpeed>2.25</fMaxSpeed>
               <fPadTime>1</fPadTime>
               <iMeleeWaveSize>1</iMeleeWaveSize>
               <iRangedWaveSize>1</iRangedWaveSize>
                   <UnitMeshGroup>
                       <iRequired>1</iRequired>
                       <EarlyArtDefineTag>ART_DEF_UNIT_NETHERLANDS_OOSTINDIEVAARDER</EarlyArtDefineTag>
                   </UnitMeshGroup>
               </UnitMeshGroups>
               <FormationType>FORMATION_TYPE_DEFAULT</FormationType>
               <HotKey/>
               <FreePromotions>
                   <FreePromotion>
                       <PromotionType>PROMOTION_STEALTH</PromotionType>
                       <bFreePromotion>1</bFreePromotion>
                   </FreePromotion>
                   <FreePromotion>
                       <PromotionType>PROMOTION_HIDDEN</PromotionType>
                       <bFreePromotion>1</bFreePromotion>
                   </FreePromotion>
               </FreePromotions>
               <bNeverObsolete>1</bNeverObsolete>
               <iCombatDefense>4</iCombatDefense>
               <iTier>1</iTier>
               <bCanMoveLimitedBorders>1</bCanMoveLimitedBorders>
               <iWithdrawlProbDefensive>40</iWithdrawlProbDefensive>
               <PrereqBuildingClass>BUILDINGCLASS_SMUGGLERS_PORT</PrereqBuildingClass>
               <PythonPostCombatLost>postCombatLostMerchant(pCaster, pOpponent)</PythonPostCombatLost>
           </UnitInfo>
    I'm sure it is not relevant, but since it is referenced in that define I'll show that postCombatLostMerchant is used to give whoever captures a merchant vessel a random amount of gold based on how much it could have gained from a trade mission.
    Code:
    def postCombatLostMerchant(pCaster, pOpponent):
       info = gc.getUnitInfo(pCaster.getUnitType())
       iPlayer = pCaster.getOwner()
       pPlayer = gc.getPlayer(iPlayer)
       iPlayerO = pOpponent.getOwner()
       pPlayerO = gc.getPlayer(iPlayerO)
       iTradeGoods = CyGame().getSorenRandNum(info.getBaseTrade(), "Merchant base" + str(pCaster.getName()) +" Raided by " + str(pOpponent.getName()))
       pCity = CyMap().findCity(pCaster.getX(), pCaster.getY(), iPlayer, TeamTypes.NO_TEAM, False, pCaster.getDomainType() == gc.getInfoTypeForString('DOMAIN_SEA'), TeamTypes.NO_TEAM, DirectionTypes.NO_DIRECTION, pPlayer.getCity(-1))
       pCityO = CyMap().findCity(pCaster.getX(), pCaster.getY(), iPlayerO, TeamTypes.NO_TEAM, False, pCaster.getDomainType() == gc.getInfoTypeForString('DOMAIN_SEA'), TeamTypes.NO_TEAM, DirectionTypes.NO_DIRECTION, pPlayerO.getCity(-1))
       if pCity.isNone():
           pCity = pPlayer.getCapitalCity()
       if pCityO.isNone():
           pCityO = pPlayerO.getCapitalCity()
       if not (pCity.isNone() or pCityO.isNone()):
           iProfit = pCity.calculateTradeProfit(pCityO) * info.getTradeMultiplier()/4
           if iProfit > 0:
               iTradeGoods += CyGame().getSorenRandNum(iProfit, "Merchant modifier" + str(pCaster.getName()) +" Raided by " + str(pOpponent.getName()))
       if iTradeGoods > 0:
           pPlayerO.changeGold(iTradeGoods)
           CyInterface().addMessage(iPlayerO, True, 25, CyTranslator().getText("TXT_KEY_MESSAGE_GOLD_FROM_COMBAT", (iTradeGoods,)), '', 1, info.getButton(), ColorTypes(8), pCaster.getX(), pCaster.getY(), True, True)
    


    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. Neither influenced whether the unit could enter cities.




    By the way, I have noticed that invisible units (if they do not have Blitz or Hidden Nationality) that have already attacked in the current turn so cannot attack again (I generally see this with summoned Angels of Death) are able to enter tiles occupied by enemy units (including enemy cities), but that invisible units with <bOnlyDefensive>1</bOnlyDefensive> never can. That behavior strikes me as odd.

    It would be much more interesting if invisible + only defensive units (like Agents of Esus) could enter enemy occupied tiles to use spells like Kidnap, Steal, Embezzle, Disrupt, etc or abilities like Destroy Production or Steal Plans.


    p.s. If CvUnit::isBlockading() is exposed in the next release you might as well include this new WBUnitScreen.py (and a WorldBuilder_CIV4GameText.xml with one new tag it uses) so that Worldbuilder can be used to change whether a unit is blockading. I have attached the files.
     

    Attached Files:

    Last edited: Jul 27, 2019
  20. Tielby

    Tielby Prince

    Joined:
    Sep 23, 2007
    Messages:
    313
    Location:
    The sacred and free citadel of mind
    Are you sure they can do this now? AFAIK, caravels cannot carry hidden nationality units, so couldn't carry a nightwatch unless it'd declared nationality. Maybe you're thinking of pirates. They can carry hidden nationality units.
     
    Last edited: Jul 27, 2019

Share This Page