Quick Modding Questions Thread

Discussion in 'Civ4 - Creation & Customization' started by kiwitt, Jan 27, 2010.

  1. Set

    Set Prince

    Joined:
    Mar 31, 2010
    Messages:
    325
    Thank you! Good to know. Decided to give warriors the UNITAI_PILLAGE mission to see if that gets the AI plotting faster. So far seems to have worked a little. There are a lot of other things that may be preventing the AI from plotting so early in the game though.

    One of these days I'm going to have to do a deep dive and figure out how the AI works. Often feels like the biggest limitation on doing cool modding stuff is knowing how the AI will react.
     
  2. Zeta Nexus

    Zeta Nexus <{[(Nexus)]}>

    Joined:
    Jan 23, 2014
    Messages:
    4,479
    Gender:
    Male
    Location:
    In a constant brainstorm...
    Please, shear with us your findings.
     
  3. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,024
    Location:
    Germany
    It could also be that the AI starts preparing for war early on, but then takes a long time to assemble a city attack stack due to other early builds (settlers, workers, minimal defenders, minimal explorers) being prioritized very highly. If your mod isn't based on BBAI, then perhaps you can tell through the "enough-on-our-hands" response whether the AI has a war plan; I don't think BtS reveals that anywhere in Debug mode. (BBAI shows war plans when holding Alt while hovering over the scoreboard.)
     
    Set likes this.
  4. Set

    Set Prince

    Joined:
    Mar 31, 2010
    Messages:
    325
    I'm trying to spawn some units under specific conditions and having a lot of trouble. The general idea is that when a specific civ (the Norse) enters their first war of the game they'll spawn a big batch of free units. I've implemented this as an XML event because I wasn't sure how to keep track of the number of wars the Norse had fought using only python. I figured I could set the event to non-recurring in the XML and that way it would only occur once. So far none of this works : /

    In CvEventManager I have this:
    Spoiler :
    Code:
    def onChangeWar(self, argsList):
           'War Status Changes'
           bIsWar = argsList[0]
           iTeam = argsList[1]
           iRivalTeam = argsList[2]
        
           if (bIsWar):
               iNorseId = 15
               if ((iTeam == iNorseId) or (iRivalTeam == iNorseId) and (gc.getGame().getGameTurn() != 0)):
                   iEvent = gc.getInfoTypeForString("EVENTTRIGGER_GREAT_HEATHEN_ARMY_1")
                   iNorsePlayer = gc.getPlayer(iNorseId)
                   iNorsePlayer.initTriggeredData(iEvent, True, -1, -1, -1, -1, -1, -1, -1, -1, -1)
    

    (Norse team ID is 15)

    and in CvRandomEventInterface I have this:
    Spoiler :
    Code:
    def greatHeathenArmy_1(argslist):
       iEvent = argsList[0]
       kTriggeredData = argsList[1]
       pNorseplayer = gc.getPlayer(kTriggeredData.ePlayer)
       iUnitLongship = gc.getInfoTypeForString("UNIT_VIKING_LONGSHIP")
       iUnitBerserker = gc.getInfoTypeForString("UNIT_VIKING_BERSERKER")
       iUnitBatteringRam = gc.getInfoTypeForString("UNIT_BATTERING_RAM")
       iUnitHorseman = gc.getInfoTypeForString("UNIT_HORSEMAN")
       iUnitLongbowman = gc.getInfoTypeForString("UNIT_LONGBOWMAN")
     
       for x in range(10):
           pNorsePlayer.initUnit(iUnitLongship, 62, 40, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_WEST)
       for x in range(15):
           pNorsePlayer.initUnit(iUnitBerserker, 62, 40, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_WEST)
       for x in range(6):
           pNorsePlayer.initUnit(iUnitBatteringRam, 62, 40, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_WEST)
       for x in range(6):
           pNorsePlayer.initUnit(iUnitHorseman, 62, 40, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_WEST)
       for x in range(3):
           pNorsePlayer.initUnit(iUnitLongbowman, 62, 40, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_WEST)
    


    In EventTriggerInfos I have what you'd expect: <iPercentGamesActive> is 100, <iWeight>-1</iWeight> and everything else set to -1/0/NONE. <bRecurring> is set to 0.

    In EventInfos everything is -1/0/NONE except I have <PythonCallback>greatHeathenArmy_1</PythonCallback>.

    The event triggers properly, ie. when the Norse declare war on someone else I get the event pop-up. But it triggers every time the norse declare war rather then only the first time. I also get the following python exception when the event triggers:

    "NameError: Global name argsList is not defined"

    in CvRandomEventInterface. And then no units spawn.

    I don't really know how argsLists work for python events. I've imitated firaxis as much as possible, pulling from the barbarian uprising event. Nor sure what's causing this exception.

    Also not sure if I'm using the right method for this kind of effect. Looking at RFC for instance I can see that the conquerors event is run using scripts. But I don't know how scripts work and I can't find any information out there about how they work.
     
  5. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,024
    Location:
    Germany
    This at least is easy to explain -- you've typed it with a lower-case L here:
    def greatHeathenArmy_1(argslist):
     
  6. Set

    Set Prince

    Joined:
    Mar 31, 2010
    Messages:
    325
    That will teach me to mod late at night :)

    Fixed now (and a lower case p as well). The code still doesn't do what I want it too. Setting recurring to 0 doesn't seem to stop it from triggering multiple times. The work around for now is to make it a python only event and associate a building with it. The event places the building there and as long as the building remains the event can't trigger again. Thanks to the circumstances of the mod I don't think I have to worry about the city being razed or anything. But I do imagine there is a better way to do this!
     
  7. lfgr

    lfgr King

    Joined:
    Feb 6, 2010
    Messages:
    965
    Calling initTriggeredData ignores this. It's only used when triggering events the normal way.

    Do you use BUG? Then you can save a flag via BugData to remember that it already has been triggered. Here's some (untested) sample code:

    Code:
    table = BugData.getTable( "YourModID" )
    if "greatHeathenArmyTriggered" not in table :
        # Do things
        table["greatHeathenArmyTriggered"] = True
    
    Behild the scenes, BUG uses ScriptData to store that stuff.
     
    Set likes this.
  8. LPlate2

    LPlate2 Warlord

    Joined:
    Dec 27, 2018
    Messages:
    232
    Hi, I’m trying to import some unit art styles. In some cases, it’s working perfectly. For some other units, the new unit artstyle only appears to be applied to one of the units in a group and the others keep the default unit art. Has anyone come across this before? What causes it and how do you fix it?
     
  9. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    411
    I'm troubleshooting this exact thing right now. I was thinking perhaps the order the units are listed may matter. Probably not, but no idea what it could be.
     
  10. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    411
    OK. Nevermind. I'm dumb. :blush:
    Apparently, you can omit one of the <StyleUnit> tags, and it doesn't throw an error. Everything after than simply doesn't get used in the game. So, double check the tags to ensure they are correct.:scan:
     
  11. LPlate2

    LPlate2 Warlord

    Joined:
    Dec 27, 2018
    Messages:
    232
    I've removed duplicate <UnitMeshGroup> entries and this seems to have sorted the issue.

    Edit: This is not a good fix. It messes up where a civ's artstyle uses more than one unitarttinfo for a unit.
     
    Last edited: Jul 12, 2021
  12. Set

    Set Prince

    Joined:
    Mar 31, 2010
    Messages:
    325
    After reinventing the wheel many times I'm trying to make use of PyHelpers but getting a crash on startup.
    Code:
    from CvPythonExtensions import *
    import CvUtil
    import CvScreensInterface
    import CvDebugTools
    import PyHelpers
    import CvWBPopups
    import Popup as PyPopup
    import CvCameraControls
    import CvTopCivs
    import sys
    import CvWorldBuilderScreen
    import CvAdvisorUtils
    import CvTechChooser
    
    # constants
    gc = CyGlobalContext()
    PyPlayer = PyHelpers.PyPlayer
    PyInfo = PyHelpers.PyInfo
    cyMap = CyMap()
    cyGame = CyGame()
    pyGame = PyGame()
    Seems like civ really doesnt like:
    Code:
    pyGame = PyGame()
    When that line is gone the game starts fine. Though obviously code dependent on that variable does not work. I definitely don't feel too confident with any of my code but it does look like the code in Baldyr's tutorial.
     
  13. scrabbarista

    scrabbarista Chieftain

    Joined:
    Aug 8, 2019
    Messages:
    42
    I'm using Genghis Kai's GEM, and when I go into WB to place civ start locations, then save the file to play as a scenario, the civs are not where I saved them. Instead, all of the settlers and warriors are piled up on top of each other in some obscure location where most of them will never even get access to enough space to found their first city. This seems to be a problem related to placing more than 50 civs on the map, though I'm not entirely sure even of that much. I have previously had success with 49-Civ scenarios, but it's been so long that I don't really remember how I did it. Over 50, however, is something I haven't figured out. I am using a 100CivDLL that works just fine, so I don't think it's that (not that I know the first thing about coding). My guess is that the problem is related to the map/scenario.

    Does anyone have any idea how I could get more than 50 civs into their proper starting locations in a Giant Earth Map WB/scenario/map file? It's frustrating to waste all the time it takes to put 75-100 civs down in their real starting locations in WB, only to have the starting locations all jumbled and reset when I open the scenario.

    PS I'm playing the ROM:AND mod. Part 2, I think.
     
    Last edited: Jul 14, 2021
  14. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,024
    Location:
    Germany
    @scrabbarista: If you open the scenario file in a text editor, what does it say about the StartingX and StartingY coordinates? I think it should look something like this:
    Code:
    BeginPlayer
       LeaderType=LEADER_SALADIN
       CivType=CIVILIZATION_ARABIA
       Team=0
       PlayableCiv=1
       StartingX=69, StartingY=40
       [etc.]
    May also want to verify that the number of players and teams in the scenario file matches the maximal numbers allowed by your DLL. (That said, if you've used the same DLL for saving the scenario as for loading it, then I don't see how there could be a mismatch.)
     
  15. raystuttgart

    raystuttgart Civ4Col Modder Supporter

    Joined:
    Jan 24, 2011
    Messages:
    7,523
    Gender:
    Male
    Location:
    Stuttgart, Germany
    All you need to do is this:

    1. Start a Game with this Scenario
    2. Open Worldbuilder and save it as new WorldbuilderSave

    --> All Player should now have their locaions assigned in your new WorldbuilderSave.

    But it will also have saved a lot more than that of course. e.g. the GameSettings you had chosen.
    If you want to still be able to change them, open the Worldbuilder Save e.g. with Notepad++ and copy according settigs from the original Scenario (also a WorldbuilderSave).

    ----

    Doing it like @f1rpo suggested is also possible, but it is a lot more effort than just creating a new WorldbuilderSave.
    (And more prone to errors.)
     
  16. scrabbarista

    scrabbarista Chieftain

    Joined:
    Aug 8, 2019
    Messages:
    42
    This misses the point. If I start the scenario with over 50 civs, then many of them end up starting literally on the same tile. I don't want that, so I wouldn't save that. Instead, I manually placed them all where I wanted them, and saved it. Unfortunately, they were still on top of each other when I reopened my saved work to play it as a scenario.
     
  17. scrabbarista

    scrabbarista Chieftain

    Joined:
    Aug 8, 2019
    Messages:
    42
    IIRC, I'd checked, and they had been moved from where I put them to being on the same XY spots.

    I saw in another thread that a guy wanted to do the same thing and said he started at 100 and worked his way down to see how many civs the map could handle without this bug. IIRC, he got to 70.

    EDIT: That was a planet generator, not the GEM.

    EDIT2: I'm also not sure that was RoM.

    Anyway, I've drifted into making yet another 50 civ scenario and am having a ton of fun playing as Indonesia right now.

    I have a question about that that I'll post right under this. Thank you for your reply! If/When I get back around to this scenario idea, I'll be sure to pay close attention to XY's in the xml. I don't think it's the dll, because I always use the same one.
     
    Last edited: Aug 6, 2021
    f1rpo likes this.
  18. scrabbarista

    scrabbarista Chieftain

    Joined:
    Aug 8, 2019
    Messages:
    42
    I have a question about modding a RoM AND2 scenario.

    I've given each of the religions tech and holy cities, etc., to their appropriate civs. My scenario starts in 1367, so what ends up happening is that each civ founds its religion on the first turn. This is all well and good as far as playability, but it's slightly annoying that the religions screen says "founded 1367" for every religion. It looks cheesy.

    Is there a way I could edit this screen to give my preferred founding dates for each religion?
     
  19. scrabbarista

    scrabbarista Chieftain

    Joined:
    Aug 8, 2019
    Messages:
    42
    And while I'm here... I've used a handful of "replacement civs" to represent the actual ones I wanted when they weren't available.

    I use Morocco as Algeria, Mutapa as Tanzania, and two Chinas (Taiwan) and two Koreas. I used Arabia as Saudi Arabia. I used Ottomans for Turkey.

    I think the other 43 civs I wanted were already in the megapack.

    To bring this scenario to the next level, how can I get these 7 civs into it? I'm open to putting in entirely new civs (not creating them myself, though) or else just changing the names/titles and maybe the flags. (I've seen some flag mod threads already.) It would be enough for me if just the names and titles were different, tbh. I'm less concerned about UU's, UB's etc. It'd just be so much cooler if it said "Tanzania" instead of "Mutapa," that's all.

    I downloaded Taiwan before, but wasn't sure how to make it playable with the other 120 or so civs in the megapack + BTS.

    PS The theory behind the scenario is that the balance of power is commensurate with the real world in 2021, but overall development is more like it was in 1300 - 1400. I think only the US has Rennaissance tech, and many civs are ancient and classical. China is massive and powerful. The US is great, too. My point is, "realism" is not the absolute standard for this scenario: Roosevelt is leading America in 1367 when the game opens. That said, I still want it to be as immersive as possible to the fantasy/alternate history I've imagined.
     
    Last edited: Jul 25, 2021
  20. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,024
    Location:
    Germany
    Seeing that the turn-founded stored by the DLL can't be modified through Python, hardcoding the dates in Assets\Python\Screens\CvReligionScreen.py may indeed be your best bet. I think this is the loop you'd have to modify:
    Code:
    xLoop = self.X_RELIGION_START
    for iRel in self.RELIGIONS:
        if (gc.getGame().getReligionGameTurnFounded(iRel) >= 0):
            szFounded = CyGameTextMgr().getTimeStr(gc.getGame().getReligionGameTurnFounded(iRel), False)
            screen.setLabelAt("", szArea, szFounded, CvUtil.FONT_CENTER_JUSTIFY,
                   xLoop, self.Y_FOUNDED, self.DZ, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
       xLoop += self.DX_RELIGION
    Not all that easy to implement. The self.RELIGIONS list (which doesn't exist in Vanilla Civ 4, it's an AND thing) may contain the ids of all religions or only of those already founded, depending on an option on the BUG menu. The ids correspond to the order of XML\GameInfo\Civ4ReligionInfos.xml, starting at 0. getTimeStr expects a turn number, but I guess it would be more convenient to provide a year number. Unfortunately, no utility function for converting past years to turn numbers seems to exist. You could simply enter year strings ("AD 50" or so), but then you don't have translations. If you do use game turn numbers, you'll get different years for different game speed settings.
     

Share This Page