Mod Component Requests Thread

Sorry I got a notification of the above message (I didn't quote properly when I answered earlier today),
Was trying to help you with your Spain request. I had it on my to-do list for a while.
LOL:lol::lol::lol:!
I totally forgot about that!
Yeah I'm sorry I forgot to mention that now I can do even much more complicated stuff using python so that is basically the easiest thing to do now!
I even made a Tutorial on how to do this here: https://forums.civfanatics.com/threads/easily-modding-in-python.663636/
 
LOL:lol::lol::lol:!
I totally forgot about that!
Yeah I'm sorry I forgot to mention that now I can do even much more complicated stuff using python so that is basically the easiest thing to do now!
I even made a Tutorial on how to do this here: https://forums.civfanatics.com/threads/easily-modding-in-python.663636/

Cool, good to see you improved in python.
It was not the hardest request no, it was in the back of my mind and then I got a popup to do it yesterday for some reason so just posted.

It's interesting to see you used Events, I didn't know how that worked and I have modded the game extensively in all direction now.

I would have just done it on "onTechAcquired" in CvEventManager, similarly easy but only one location to change. I wonder if it makes a difference in terms of resources consumed
 
Cool, good to see you improved in python.
It was not the hardest request no, it was in the back of my mind and then I got a popup to do it yesterday for some reason so just posted.

It's interesting to see you used Events, I didn't know how that worked and I have modded the game extensively in all direction now.

I would have just done it on "onTechAcquired" in CvEventManager, similarly easy but only one location to change. I wonder if it makes a difference in terms of resources consumed
Yes, now I would also probably do it onTechAcquired in the CvEventManager but before I was a newbie at python and doing it with events is much easier.
I have to thank spillsandstains who helped me a lot with python.
 
Hey, everybody. I need my engineer to learn how to do hill from peak. I know this has been addressed here before, but I didn't need it at the time and now I can't find the code. Can someone help me please?
 
Hey, everybody. I need my engineer to learn how to do hill from peak. I know this has been addressed here before, but I didn't need it at the time and now I can't find the code. Can someone help me please?

There are several options. Here is the ready-made code, you just need to replace the unit.
https://forums.civfanatics.com/resources/pioneertank.11674/

Yeah. I searched for six hours today with my really bad English with no luck. so I'm asking for help.

Hm. Browsers have a built-in auto-translator (right mouse button). But for some reason, no one appreciates or respects them:dunno:
 
Thank you. I already use Pioneertank. The problem is that I can't use it on peak, even if I enable the pioneer tank on impasable terrain :(
 
The problem is that I can't use it on peak, even if I enable the pioneer tank on impasable terrain

Hmm, as far as I understand, in order for the tank to work properly, you need to add the "peak" improvement to ImprovementInfos.xml and in UnitBuildInfos.xml. If this doesn't work, then the author of the code is The_J and he is on the forum. Perhaps he will tell you something.
 
Last edited:
My modding experience is almost entirely with FfH2 based mods, where I would assume the natural choice for plot type changing abilities would be to implement them as spells rather than dummy builds.

However, I am pretty sure that the game does not allow improvements to be built on peaks by default, but that you can override that in python using the def canBuild(self,argsList) callback in CvGameUtils.py.

Here is the def canBuild(self,argsList) from my modmod. You can ignore most of it, but see how returning a 1 in a peak when constructing specific improvements allows them to be built anyway.
Spoiler :

Code:
    def canBuild(self,argsList):
        iX, iY, iBuild, iPlayer = argsList
        pPlot = CyMap().plot(iX, iY)
        pPlayer = gc.getPlayer(iPlayer)
        iImprovement = pPlot.getImprovementType()
        iImprovementNew = gc.getBuildInfo(iBuild).getImprovement()
        iBonus = pPlot.getBonusType(pPlot.getTeam())
        #I don't want mana nodes blocked by farms, mines, etc
        if iBuild == gc.getInfoTypeForString('BUILD_GRAVEYARD'):
            if pPlayer.getStateReligion() != gc.getInfoTypeForString('RELIGION_ETERNAL_CABAL'):
                return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_FARM'):
            if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_FALLOW')):
                return 0
            if pPlayer.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_GRIGORI'):
                return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_HOMESTEAD'):
            if pPlayer.getCivilizationType() != gc.getInfoTypeForString('CIVILIZATION_GRIGORI'):
                return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_CITADEL_OF_LIGHT'):
            if pPlayer.getStateReligion() != gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'):
                return 0
            if iImprovement != gc.getInfoTypeForString('IMPROVEMENT_CITADEL'):
                return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_LUMBERMILL'):
            if pPlayer.getStateReligion() == gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES'):
                return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_REMOVE_FOREST'):
            if pPlayer.getStateReligion() == gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES'):
                if iImprovement != gc.getInfoTypeForString('IMPROVEMENT_SMOKE'):
                    return 0
        elif iBuild == gc.getInfoTypeForString('BUILD_MANA_ICE'):
            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:
                        if gc.getTeam(pPlayer.getTeam()).isAtWar(pAuricPlayer.getTeam()):
                            return 0
        if iImprovementNew > -1:
            if iImprovement == iImprovementNew:
                return 0
            if iBonus != -1:
                if gc.getBonusInfo(iBonus).isMana():
                    iBonusNew = gc.getImprovementInfo(iImprovementNew).getBonusConvert()
                    if iBonusNew == -1:
                        return 0
            if pPlot.isOwned():
                if pPlot.getTeam() == pPlayer.getTeam():
                    if iImprovement != -1:
                        if iImprovement == gc.getImprovementInfo(iImprovementNew).getImprovementPillage():
                            return 1
                    if pPlot.isPeak():
                        if iBuild in [gc.getInfoTypeForString('BUILD_MINE'), gc.getInfoTypeForString('BUILD_QUARRY')]:
                            if iImprovement == -1:
                                if pPlayer.getCivics(gc.getInfoTypeForString('CIVICOPTION_LABOR')) == gc.getInfoTypeForString('CIVIC_ARETE'):
                                    return 1
                            if iBonus > -1:
                                if gc.getImprovementInfo(iImprovementNew).isImprovementBonusTrade(iBonus):
                                    return 1
            return -1
        if pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_UNDERCOUNCIL')):
            if iBuild == gc.getInfoTypeForString('BUILD_MANA_SUN'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SUN_MANA')):
                    return 0
        elif pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_OVERCOUNCIL')):
            if iBuild == gc.getInfoTypeForString('BUILD_MANA_CHAOS'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_CHAOS_MANA')):
                    return 0
            elif iBuild == gc.getInfoTypeForString('BUILD_MANA_DEATH'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DEATH_MANA')):
                    return 0
            elif iBuild == gc.getInfoTypeForString('BUILD_MANA_DIMENSIONAL'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DIMENSIONAL_MANA')):
                    return 0
            elif iBuild == gc.getInfoTypeForString('BUILD_MANA_ENTROPY'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_ENTROPY_MANA')):
                    return 0
            elif iBuild == gc.getInfoTypeForString('BUILD_MANA_SHADOW'):
                if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SHADOW_MANA')):
                    return 0
            elif iBuild == gc.getInfoTypeForString('BUILD_PLANTATION'):
                if iBonus == gc.getInfoTypeForString('BONUS_DESERT_ROSE'):
                    if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DESERT_ROSE')):
                        return 0
                elif iBonus == gc.getInfoTypeForString('BONUS_GULAGARM'):
                    if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_GULAGARM')):
                        return 0
                elif iBonus == gc.getInfoTypeForString('BONUS_RAZORWEED'):
                    if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_RAZORWEED')):
                        return 0
                elif iBonus == gc.getInfoTypeForString('BONUS_SHEUT_STONE'):
                    if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SHEUT_STONE')):
                        return 0
        if not pPlayer.isHuman():
            iCiv = pPlayer.getCivilizationType()
            if iCiv in [gc.getInfoTypeForString('CIVILIZATION_LJOSALFAR'), gc.getInfoTypeForString('CIVILIZATION_SVARTALFAR')]:
                if iBuild in [gc.getInfoTypeForString('BUILD_REMOVE_FOREST'), gc.getInfoTypeForString('BUILD_LUMBERMILL')]:
                    return 0
            elif iCiv == gc.getInfoTypeForString('CIVILIZATION_INFERNAL'):
                if iBuild == gc.getInfoTypeForString('BUILD_MANA_LIFE'):
                    if pPlayer.getArcaneTowerVictoryFlag() != 1:
                        return 0
            elif iCiv == gc.getInfoTypeForString('CIVILIZATION_MERCURIANS'):
                if iBuild in [gc.getInfoTypeForString('BUILD_MANA_CHAOS'), gc.getInfoTypeForString('BUILD_MANA_DEATH'), gc.getInfoTypeForString('BUILD_MANA_DIMENSIONAL'), gc.getInfoTypeForString('BUILD_MANA_ENTROPY')]:
                    if pPlayer.getArcaneTowerVictoryFlag() != 3:
                        return 0
        return -1# Returning -1 means ignore; 0 means Build cannot be performed; 1 or greater means it can

Note that I did not have to change anything in python in order to let units built roads or railroads on peaks.

You could probably simplify things by using a dummy Route type instead of a dummy Improvement, using the onRouteBuilt callback instead of
onImprovementBuilt, pPlot.setRouteType(-1) instead of pPlot.setImprovementType(-1)
 
You've got a buckle. Now I realize I have a special unit that has access to impassable squares and can build a route there.
I'm not a programmer, but I can try to somehow apply The_J path with route type. Thank you.
 
However, I am pretty sure that the game does not allow improvements to be built on peaks by default, but that you can override that in python using the def canBuild(self,argsList) callback in CvGameUtils.py.

I've not had a look at any of the files for at minimum 6 years, so my memory is fuzzy, and I need some help freshing up:
Is a peak a terrain like grass or tundra, or was there something special about that one? (I think I vaguely remember something; or is there a TERRAIN_PEAK?)
If roads can by default be built, then this shouldn't be, right?

I can have a look and see if I can plug some code into canBuild, but I'm not sure if that'll just work, given what I've forgotten :lol: (and I can't test, no Civ4 anymore).
 
I think there is a dummy terrain called peak (I'm on my phone away from home so I cannot check at the moment), but it doesn't really matter.

I think Fireaxis started to implement it like other terrains and just left it there despite changing the game engine so it does not use it.

Peaks, Hills, Flat Land, and Water are Plot Types.

Every plot must have a plot type as well as a terrain.

I think most maps scripts tend to make peaks have desert terrain, as the spring and vitalize spells in FfH2 work there.

Regardless of the terrain, a peak will have 0 yields and so cannot be worked, unless you increase the yields in Python or by adding improvements or features.
 
:think: can anyone give me a standard terrain_types.xml and plot_types.xml (these were the names, right?)?
I need to have a look at them.

EDIT: Since hrochland anyways wants to change the plot type to hills it shouldn't be an issue that there are no yields from peaks.
 
Is this from your current mod? Because it has:
<bWater>1</bWater>
set for peaks.

My main thought right now:
As long as you can build improvements on peaks, the pioneer tank should be able to build an improvement to turn the peak into a hill.
And in principle I don't see any restrictions for putting improvements on peaks.
You need to add TERRAIN_PEAKS to IMPROVEMENT_CREATE_HILL though.

If this does not work, then I don't see why :think:.
 
I took it from basic civ4
I added TERRAIN_PEAKS to IMPROVEMENT_CREATE_HILL yesterday, but it doesn't work. As I wrote above, I can only build a road on PEAK.
 
Top Bottom