Quick Modding Questions Thread

Thank you for your help.

On-screen messages also go into the Turn Log on the left. Or do you mean the popups on the right, e.g. for random events? Code for launching those would be rather verbose.
Which ever is the shortest.

I'll try the above out in my future work as soon as I figure out my next DLL task.

On a related note, I just made my first big DLL edit. Porting the Hero promotion from FFH to my mod. So yea. I am proud now. :)
 
Also, is there a vanilla way to make it so that some units can get a promotion and others can't if they are from the same unit combat. Like say I want promotion X to be available to submarines and destroyers but not battleships.

If not, is there a mod that does this and how? I'd rather copy what works than roll my own just yet.
 
Also, is there a vanilla way to make it so that some units can get a promotion and others can't if they are from the same unit combat. Like say I want promotion X to be available to submarines and destroyers but not battleships.

If not, is there a mod that does this and how? I'd rather copy what works than roll my own just yet.
Simple noob solution:
Those promotions require a dummy promotion that these units start with. It's just xml work but you may want something more elegant.
 
I thought of that as well. But as you said, I am looking for something more elegant as these won't show up in the wiki in a reasonable way.

Also, what does adding a new unit_combat entail? Do I need to change anything in the DLL to make the AI figure it out?

Also, how do Unit_combats work in general? Like is the AI programmed to treat units based on them? Like for example always using Archers for defense etc? Or is this done on a unit per unit basis?
Like say if I wanted to reuse the existing ones that I don't need for something else (like renaming archers to heavy infantry) how would that effect the AI?
 
Last edited:
I haven't tried it, but I don't think any AI change or other DLL change is needed or desirable when adding new unit combat types. The C++ code does not reference any specific UNITCOMBAT_... string or enumerator at all (just ran a quick search on the codebase).
Like for example always using Archers for defense etc? Or is this done on a unit per unit basis?
Such AI behavior is tied to Unit AI types (e.g. UNITAI_CITY_DEFENSE) and the AI also looks at most of the special abilities to figure out the appropriate role of a unit (CvPlayerAI::AI_unitValue). So an additional combat class seems like a clean, low-effort approach for restricting promotions. Making a new icon might be the biggest subtask. Removing or replacing unit combat classes should also be fine - so long as references in XML (e.g. random events) are cleaned up. (Renaming could also just be a game text change.)
 
Making a new icon might be the biggest subtask.
Why do you say that? :confused:
I can make a new icon in less than 2 minutes (or it can take an hour if I am really into details).
 
Why do you say that? :confused:
I can make a new icon in less than 2 minutes (or it can take an hour if I am really into details).
Because it has to fit in with the other icons. Like, I can make an icon real quick as well but making it actually look like it was made in the original game is harder.
I mean, it basically has to fit within 3-4 shades of yellow and yet still convey both shape and form.
 
Last edited:
I can make a new icon in less than 2 minutes (or it can take an hour if I am really into details).
I figured that other modders can create graphics much faster than I could, but, well, two minutes is fast; I don't think I could do the XML for a new unit combat type (Civ4BasicInfos.xml, Civ4UnitInfos.xml, Civ4PromotionInfos.xml, game text) in two minutes – but it looks like the XML shouldn't take far longer either.
 
I am just going to rename the existing ones. :) Well, I did.
The icons will take a while though.
 
I knew this but I forgot. What's the proper encoding for DDS files that produces minimal artifacting and compression but still works with the game?
Like, I even had it written down and I can't find where I did.
 
I figured that other modders can create graphics much faster than I could, but, well, two minutes is fast; I don't think I could do the XML for a new unit combat type (Civ4BasicInfos.xml, Civ4UnitInfos.xml, Civ4PromotionInfos.xml, game text) in two minutes – but it looks like the XML shouldn't take far longer either.
Okay, I was afraid that there was some other catch I wasn't aware of 🙂
 
Okay, I was afraid that there was some other catch I wasn't aware of 🙂
You mean other than trying to convey abstract concept through a monochrome 64x64 image that has to fit into the general art style of the game?
Like if you want to help feel free to call.
 
You mean other than trying to convey abstract concept through a monochrome 64x64 image that has to fit into the general art style of the game?
I meant some programing issues, when you cannot just simply create the image but has something else to code also.


Like if you want to help feel free to call.
I already offered my help 😉
 
I'm trying to merge a python wonder effect from Civ Gold Revived to my mod as a project effect and I want to know if I'm doing it right.

I have the following code in Civ Gold Revived in CvEventManager.py:

Python:
    def onCityAcquired(self, argsList):
        'City Acquired'
        iPreviousOwner,iNewOwner,pCity,bConquest,bTrade = argsList
        CvUtil.pyPrint('City Acquired Event: %s' %(pCity.getName()))

        pPlayer = gc.getPlayer(iPreviousOwner)
        iTeam = pPlayer.getTeam()
        pTeam = gc.getTeam(iTeam)
        pPlayer2 = gc.getPlayer(iNewOwner)
        iTeam2 = pPlayer2.getTeam()
        pTeam2 = gc.getTeam(iTeam2)
      
        ## Lot of other wonder effect in between ##
      
        ## Torre del Oro Start ##
        if pCity.getNumActiveBuilding(gc.getInfoTypeForString("BUILDING_TORRE_DEL_ORO")):
            for iTech in xrange(gc.getNumTechInfos()):
                if gc.getTechInfo(iTech).getAdvisorType() == gc.getInfoTypeForString("ADVISOR_MILITARY"):
                    if not pTeam.isHasTech(iTech):
                        research_cost = pTeam.getResearchCost(iTech)
                        pTeam.changeResearchProgress(iTech, - research_cost *3/20, iPreviousOwner)
                    if not pTeam2.isHasTech(iTech):
                        research_cost = pTeam2.getResearchCost(iTech)
                        pTeam2.changeResearchProgress(iTech, min(research_cost - pTeam.getResearchProgress(iTech), research_cost *3/20), iNewOwner)

and



Python:
    def onBuildingBuilt(self, argsList):
        'Building Completed'
        pCity, iBuildingType = argsList
        game = gc.getGame()

        iPlayer = pCity.getOwner()
        pPlayer = gc.getPlayer(iPlayer)
        iTeam = pPlayer.getTeam()
        pTeam = gc.getTeam(iTeam)
      
      
        ## Lot of other wonder effect in between ##
      
        ## Torre del Oro Start ##
        if iBuildingType == gc.getInfoTypeForString("BUILDING_TORRE_DEL_ORO"):
            for iTech in xrange(gc.getNumTechInfos()):
                if not pTeam.isHasTech(iTech):
                    if gc.getTechInfo(iTech).getAdvisorType() == gc.getInfoTypeForString("ADVISOR_MILITARY"):
                        research_cost = pTeam.getResearchCost(iTech)
                        pTeam.changeResearchProgress(iTech, min(research_cost - pTeam.getResearchProgress(iTech), research_cost *3/20), iPlayer)

and

Python:
    def onCityRazed(self, argsList):
        'City Razed'
        city, iPlayer = argsList
        iOwner = city.findHighestCulture()

        pPlayer = gc.getPlayer(iPlayer)
        iTeam = pPlayer.getTeam()
        pTeam = gc.getTeam(iTeam)

        ## Lot of other wonder effect in between ##
      
        ## Torre del Oro Start ##
        if city.getNumActiveBuilding(gc.getInfoTypeForString("BUILDING_TORRE_DEL_ORO")):
            for iTech in xrange(gc.getNumTechInfos()):
                if not pTeam.isHasTech(iTech):
                    if gc.getTechInfo(iTech).getAdvisorType() == gc.getInfoTypeForString("ADVISOR_MILITARY"):
                        pTeam.changeResearchProgress(iTech, - pTeam.getResearchCost(iTech) *3/20, iPlayer)

So if I understand things properly, than it's only the second code I need, since projects cannot be captured or razed, right?

My goal is to make Theory of Evolution project make all biology techs ("ADVISOR_GROWTH") cost only half :science: .

So here's the code I want to try. Does anyone see any problem with it?
Python:
    def onProjectBuilt(self, argsList):
        'Project Completed'
        pCity, iProjectType = argsList
        game = gc.getGame()
        if ((not gc.getGame().isNetworkMultiPlayer()) and (pCity.getOwner() == gc.getGame().getActivePlayer())):
            popupInfo = CyPopupInfo()
            popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
            popupInfo.setData1(iProjectType)
            popupInfo.setData2(pCity.getID())
            popupInfo.setData3(2)
            popupInfo.setText(u"showWonderMovie")
            popupInfo.addPopup(pCity.getOwner())

## Periodic Theory of Evolution ##
        if iProjectType == gc.getInfoTypeForString("PROJECT_THEORY_OF_EVOLUTION"):
            for iTech in xrange(gc.getNumTechInfos()):
                if not pTeam.isHasTech(iTech):
                    if gc.getTechInfo(iTech).getAdvisorType() == gc.getInfoTypeForString("ADVISOR_GROWTH"):
                        research_cost = pTeam.getResearchCost(iTech)
                        pTeam.changeResearchProgress(iTech, min(research_cost - pTeam.getResearchProgress(iTech), research_cost *10/20), iPlayer)

Thank you in advance! :)


EDIT:
After a quick test it is clear to me that this code doesn't work. So what am I doing wrong? :think:
 
Last edited:
After a quick test it is clear to me that this code doesn't work. So what am I doing wrong? :think:
Perhaps you're missing this stuff:
Code:
	iPlayer = pCity.getOwner()
	pPlayer = gc.getPlayer(iPlayer)
	iTeam = pPlayer.getTeam()
	pTeam = gc.getTeam(iTeam)
Is there a Python error?
 
Perhaps you're missing this stuff:
Code:
    iPlayer = pCity.getOwner()
    pPlayer = gc.getPlayer(iPlayer)
    iTeam = pPlayer.getTeam()
    pTeam = gc.getTeam(iTeam)

Yaay! That was it! :woohoo:
Thank you again, oh great wizard* :bowdown:

*or whatever title you prefer
 
Sure, that'll work. :blush: Wizard, wise one, istar ...

Anyway, great. A one-time effect like this really should only require that one change as far as I can tell. AI - well, will have to make do with iAIWeight in XML.
 
AI - well, will have to make do with iAIWeight in XML.
Unfortunatelly there is no such tag for Projects. Not even in the whole AND_CIV4GameInfoSchema.xml.

Or iAIWeight is universal and can be used anywhere? :confused:
 
No, you're right. Could only do something in the DLL, e.g.
Code:
if (eProject == GC.getInfoTypeForString("PROJECT_THEORY_OF_EVOLUTION"))
	iValue += 5;
in CvCityAI::AI_projectValue. Not sure how that value gets used; seems to be on a pretty small scale:
Spoiler :
Code:
if (GC.getProjectInfo(eProject).getNukeInterception() > 0)
{
	if (GC.getGameINLINE().canTrainNukes())
		iValue += (GC.getProjectInfo(eProject).getNukeInterception() / 10); // (Only 7 gets added here it seems)
}
Edit: Oh, AND has tweaked this:
Code:
iValue += (GC.getProjectInfo(eProject).getNukeInterception() *2);
 
Back
Top Bottom