Quick Modding Questions Thread

How do the Rands (iRandApp1, iRandApp2, iRandApp3 & iRandApp4) work in bonus placement?
 
And once the game has started, you could remove the leading number. It might also be possible to prepend numbers only while the EXE is sorting the list. In the debugger, I see that the EXE calls CvInfoBase::getDescription repeatedly for each civ as the civ selection screen (under Play Now) is loaded, so it looks like getDescription gets called for every comparison that occurs while sorting the list. But I'm not sure if getDescription is called one last time for each civ when sorting is over, i.e. when the descriptions are put on the screen. And even if so, identifying that last call would be difficult.
Thanks a lot, this worked!
Spoiler :

Identifying the last call wasn't actually the most difficult thing; I spent way more time trying to figure out a way to reset the amount of tracked getDescription calls as soon as a scenario is loaded (that's what the resetAsked() function is for). If anyone is interested, here's the code I've come up with:
Code:
//bluepotato start: fix civ listing
static int* asked;
static bool civsInited = false;
static int civs;
void CvInfoBase::resetAsked() { //this is a static function. it's exposed to python and called in CvWBInterface.getPlayerData()
   for(int i = 0; i<GC.getNumCivilizationInfos(); i++) {
       asked[i] = 0;
   }
}
//bluepotato end
const wchar* CvInfoBase::getDescription(uint uiForm) const
{
   while(m_aCachedDescriptions.size() <= uiForm)
   {
       m_aCachedDescriptions.push_back(gDLL->getObjectText(m_szTextKey, m_aCachedDescriptions.size()));
   }
   //bluepotato start: fix civ listing
   int i;
   if(!civsInited) {
       civs = 0;
       asked = new int[GC.getNumCivilizationInfos()];
       for(i = 0; i<GC.getNumCivilizationInfos(); i++) {
           asked[i] = GC.getNumCivilizationInfos(); //so that civilopedia doesn't break
           if(GC.getCivilizationInfo((CivilizationTypes)i).isPlayable()) {
               civs++;
           }
       }
       civsInited = true;
   }
   for(i = 0; i<GC.getNumCivilizationInfos(); i++) {
       if(wcscmp(m_szTextKey.c_str(), GC.getCivilizationInfo((CivilizationTypes)i).getTextKeyWide()) == 0) {
           asked[i]++;
           if(asked[i]<civs) {
               return L"";
           }
       }
   }
   //bluepotato end
   return m_aCachedDescriptions[uiForm];
}
Yes, it's ugly, but it does the job.
 
Probably a dumb question, but might CvGame::isFinalInitialized() help with this?
 
Yeah I realised later that you want the default values as soon as the game retrieves what is actually being displayed.
 
Thanks a lot, this worked! [...]
Identifying the last call wasn't actually the most difficult thing; I spent way more time trying to figure out a way to reset the amount of tracked getDescription calls as soon as a scenario is loaded (that's what the resetAsked() function is for). If anyone is interested, here's the code I've come up with:
Cool. If the EXE really calls getDescription exactly once for each pair of playable civs, then I would assume that it performs an insertion sort. I can see that resetting is tricky, e.g. when the player cancels the civ selection and later comes back to it (maybe browsing the main menu Civilopedia in between). Once the game has started, it seems a bit wasteful to test for equality of m_szTextKey with every civ text key on every getDescription call. A guard
if (getGame().getActivePlayer() != NO_PLAYER)
before your code could avoid that. (Checking finalInitialized might also work.)
Yes, it's ugly, but it does the job.
For a prettier implementation (not a suggestion ... just musing), I'd let CvCivilizationInfo override getDescription. Since getDescription isn't virtual and can't be made virtual (DllExport), that would have to be done by forwarding from getDescription to a virtual protected function, say, CvInfoBase::getDescriptionInternal, which then gets overidden by CvCivilizationInfo.
 
I can see that resetting is tricky, e.g. when the player cancels the civ selection and later comes back to it (maybe browsing the main menu Civilopedia in between).
As long as the scenario selection screen is used, it can always be reset from CvWBInterface.getPlayerData() since that function is called every time the scenario civ selection screen is loaded. For mapscripts maybe getDescription could be used, but that's not relevant in my case.
Once the game has started, it seems a bit wasteful to test for equality of m_szTextKey with every civ text key on every getDescription call. A guard
if (getGame().getActivePlayer() != NO_PLAYER)before your code could avoid that. (Checking finalInitialized might also work.)
Just tried these and can confirm that both of them work. (so Leo was right, isFinalInitialized does help :))
 
Are there any xml files that control the AI's willingness to improve it's tiles? In my mod the AI is barely building improvements and I don't know why.
If a land improvement consumes the worker then the AI will tend not to build them. As far as I know all worker AI is controlled in the dll and none is available for modding through XML:(.
 
Are there any xml files that control the AI's willingness to improve it's tiles? In my mod the AI is barely building improvements and I don't know why.

In CIV4LeaderHeadInfos.xml there's a list tag "ImprovementWeightModifiers" that can weight AI's toward certain improvements. I think that's the closest you can get. Boudica, for example, has 20 "weight" toward farms and windmills. I don't think that makes her build improvements more, it just makes her build farms more when she does build improvements.

Seems to be nothing in GlobalDefines about it either :undecide:
 
Here's a very specific question. Would it be pretentious to try to start a project for a mod when the mod isn't even finished, or really even off the ground yet?

I have a potentially very cool mod that I want to put together but I'm realizing I do NOT have the time to do the XML and art for it :mischief:
 
I have a potentially very cool mod that I want to put together but I'm realizing I do NOT have the time to do the XML and art for it :mischief:
I'd volunteer to help but have very little time even for my own mod.
But why don't you create a modmod instead of mod from scratch? It may be easier to take away and reorganize a few things, than add a lot of new ones.
EDIT: To be more accurate I think I may want to merge your mod as an optional module.
 
Last edited:
If a land improvement consumes the worker then the AI will tend not to build them.
Actually I knew that - from sour experience :rolleyes:
The problem is that Workers don't build improvements, like Farms, Mines, Cottages, etc. Only on top of resources.
It is an AND2 modmod and I didn't change things drastically: I added a few more resource and improvements but did not reshuffle yield values or make it consume the unit.
So I didn't change anything that I can think of being related to it :dunno:

As far as I know all worker AI is controlled in the dll and none is available for modding through XML:(.
Was afraid of that.
 
Okay, there are a couple things I tried already:

Some civics change yields of improvements so I tried editing out all of these but made no difference.

I also tried increasing the AIWeight of Workers. The AI did train more workers but didn't use them.

I tried removing the new worker units I added thinking that maybe those confuse the AI logic, although the AI properly replaces them with Workers, as it should.

I am clueless how to solve this. Can logs help? If so, what should I look for?

EDIT: So the AI happily builds roads and improves tiles with resources, but only those. I didn't edit the AI in the dll since I am unable to.
What can be wrong :wallbash:
 
Last edited:
I don't know how extensive your modmod is, but you could try undoing all your changes to improvements and see if that fixes it, then add the changes back in one at a time until it breaks. It sounds like it's one of those complicated do-thing-A-and-thing-B-makes-thing-C-quit-working kind of things.
 
iWorkRate is the same for both so as far as I know it's just movement. I was pretty disappointed.
 
Is anyone familiar with this popup? I thought it had to do with changes I made to DiplomacyInfos.xml but replacing the edited version with the original, and re-adding normal bts leaders to the modded leaderhead file didn't fix it.

Edit: Solved. I deleted CvDiplomacyInterface.py and CvDiplomacy.py from the mod folder, and it fixed it. Not sure why this error happened here, and not in base GEM
 

Attachments

  • diplo error.png
    diplo error.png
    1.7 MB · Views: 128
Last edited:
Top Bottom