1. Firaxis celebrates the "Asian American and Pacific Islander Heritage Month", and offers a give-away of a Civ6 anthology copy (5 in total)! For all the details, please check the thread here. .
    Dismiss Notice
  2. Old World has finally been released on GOG and Steam, besides also being available in the Epic store . Come to our Old World forum and discuss with us!
    Dismiss Notice

AI founding city behavior

Discussion in 'Civ4 - SDK/Python' started by Hutma, Apr 21, 2020.

Tags:
  1. Hutma

    Hutma Chieftain

    Joined:
    Apr 21, 2020
    Messages:
    22
    Gender:
    Male
    Location:
    France
    Hello,
    I am currently creating a mod for civilization 4. In this mod the city maintenance cost from distance to the capital is reduced to almost zero. The objective is to encourage players to found cities in good locations and getting ressources even far away from their capital.
    The problem is that the AI keeps on building cities close to each others like in a vanilla game.

    So I try to edit de CvPlayerAI.cpp but I'm not very confident with C++.
    Can you help me editing the CvPlayerAI::AI_foundValue to change to AI behavior? Which values should I change?

    Thank you (I apologize for any English mistakes, it's not my native language)
     
  2. Hutma

    Hutma Chieftain

    Joined:
    Apr 21, 2020
    Messages:
    22
    Gender:
    Male
    Location:
    France
    Code:
    if (iMinDistanceFactor > 1000)
                {
                    //give a maximum boost of 25% for somewhat distant locations, don't go overboard.
                    iMinDistanceFactor = std::min(1500, iMinDistanceFactor);
                    iValue *= (1000 + iMinDistanceFactor);               
                    iValue /= 2000;
                }
                else if (iMinDistanceFactor < 1000)
                {
                    //this is too close so penalize again.
                    iValue *= iMinDistanceFactor;
                    iValue /= 1000;
                    iValue *= iMinDistanceFactor;
                    iValue /= 1000;
                }
                
                iValue /= 10;
                
                if (pPlot->getBonusType() != NO_BONUS)
                {
                    iValue /= 2;
                }
            }
        }
        
        if (bAdvancedStart)
        {
            if (pPlot->getBonusType() != NO_BONUS)
            {
                iValue *= 70;
                iValue /= 100;
            }
        }
    
        pNearestCity = GC.getMapINLINE().findCity(iX, iY, ((isBarbarian()) ? NO_PLAYER : getID()));
    
        if (pNearestCity != NULL)
        {
            if (isBarbarian())
            {
                iValue -= (std::max(0, (8 - plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE()))) * 200);
            }
            else
            {
                int iDistance = plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE());
                int iNumCities = getNumCities();
                if (iDistance > 5)
                {
                    iValue -= (iDistance - 5) * 500;               
                }
                else if (iDistance < 4)
                {
                    iValue -= (4 - iDistance) * 2000;
                }
                iValue *= (8 + iNumCities * 4);
                iValue /= (2 + (iNumCities * 4) + iDistance);
                if (pNearestCity->isCapital())
                {
                    iValue *= 150;
                    iValue /= 100;
                }
                else if (getCapitalCity() != NULL)
                {
                    //Provide up to a 50% boost to value (80% for adv.start)
                    //for city sites which are relatively close to the core
                    //compared with the most distance city from the core
                    //(having a boost rather than distance penalty avoids some distortion)
    I think I understand more this file now.
    I think I have to modify the line "iValue -= (iDistance - 5) * 500;" and replace it with "iValue -= (iDistance - 5) * 100;" for exemple, so that iValue would be less affected by distance. Am I right or wrong?
     
  3. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,158
    Location:
    Germany
    The iMinDistanceFactor stuff is only used when choosing starting locations (bStartingLoc). But the
    iValue -= (iDistance - 5) * 500;
    is right on target, and decreasing the multiplier to 100 sounds reasonable. The else branch is also relevant; it deals with founding a city on a landmass where the AI player doesn't have any cities yet:
    Code:
    else
    {
        pNearestCity = GC.getMapINLINE().findCity(iX, iY, ((isBarbarian()) ?
                NO_PLAYER : getID()), ((isBarbarian()) ? NO_TEAM : getTeam()),
                /*bSameArea=*/false);
        if (pNearestCity != NULL)
        {
            int iDistance = plotDistance(iX, iY, pNearestCity->getX_INLINE(), pNearestCity->getY_INLINE());
            iValue -= std::min(500 * iDistance, (8000 * iDistance) / GC.getMapINLINE().maxPlotDistance());
        }
    }
    I hope you're aware that you'll have to re-compile the DLL for any changes to take effect. (Just checking since you say that you're not well familiar with C++.)
     
  4. Hutma

    Hutma Chieftain

    Joined:
    Apr 21, 2020
    Messages:
    22
    Gender:
    Male
    Location:
    France
    Thank you very much for the response f1rpo, I will also modify the else branch.
    I have learned a bit of C++ since yesterday and I understand it better now (a little bit better).

    I am aware that I will have to recompile the DLL but I'm nut sure how to do it. I followed The Easiest Way to Compile a New DLL by Leoreth to open the file and setting up the C++ environment. But I haven't understood how to compile the dll and how to use the Makefile...
     
  5. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,158
    Location:
    Germany
    The makefile can be opened with any editor. Normally, it should be enough to verify that the variables on top (TOOLKIT, PSDK, YOURMOD) are set to the correct paths. If Visual Studio is installed, a double click on the .sln file should open the project, and then the F7 key can be used to start the build process. Hopefully, it'll create a new CvGameCoreDLL.dll and copy it to the YOURMOD folder. Otherwise, there should be error messages on the Visual Studio console at the bottom.
     
  6. Hutma

    Hutma Chieftain

    Joined:
    Apr 21, 2020
    Messages:
    22
    Gender:
    Male
    Location:
    France
    Thank you for taking the time to respond, you're very helpful.
    Everything seems to work during the compilation, at the end of the compilation I tried to run the game and this error poped up :
    Code:
    Assert Failed
    
    File:  .\.\CvGlobals.cpp
    Line:  3493
    Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    Message:  info type BUILDING_VERSAILLES not found, Current XML file is: xml\Buildings/CIV4BuildingInfos.xml
    
    ----------------------------------------------------------
    
    And many other like this after. It's because I removed lots of building in the mod. Should I modify the CvGlobal.cpp (if I have to, do I have to do it with units, civics etc. also?)?
    Or is there another way to go around this error and prevent other errors like this one?
     
  7. bluepotato

    bluepotato Warlord

    Joined:
    Dec 11, 2018
    Messages:
    296
    In order to get rid of these asserts you'll want to search for all instances of this XML key in all your XML files (not sure how to do that on Windows, I think Notepad++ has a directory search feature) and remove them. If you don't really care the game will probably still start without doing that, just ignore these asserts (there's a button for that), and/or compile a Release DLL instead of a Debug DLL. There's no need to change anything in CvGlobals.cpp.
     
  8. Leoreth

    Leoreth Vampire of the Blue Moon Moderator

    Joined:
    Aug 23, 2009
    Messages:
    35,727
    Gender:
    Male
    Location:
    Paris
    I disagree (slightly). Asserts are there for a reason, and if they are violated in your mod you should either check out that specific assert to see if it no longer applies, or rectify the issue. For example, here it's pointing out that your reference to BUILDING_VERSAILLES, which you presumably removed, is still showing up in your XML somewhere else. Even though it doesn't break your entire mod, there's still some issue that results from this, and you should fix it at some point. Often you are actually debugging something else of course, but in that case just choose "ignore always" to skip over that particular assert.
     
  9. bluepotato

    bluepotato Warlord

    Joined:
    Dec 11, 2018
    Messages:
    296
    By "don't really care" I meant "it's not something you want to fix right now". IMO asserts are annoying enough (rightly so) that one eventually will fix them, but after recompiling the DLL I don't think doing that is the main objective when first trying the new DLL (especially if you're new to DLL modding).
    But you're right, I wasn't really clear about this.
     
  10. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,158
    Location:
    Germany
    Happy to help.
    That would be done through the configuration manager in Visual Studio; under project properties (not to be confused with solution properties). I hadn't even thought about the build configuration when I wrote to just press F7. A debug (or assert) build is helpful, but, eventually, you'll also want a release build because that runs much faster.
     
  11. Hutma

    Hutma Chieftain

    Joined:
    Apr 21, 2020
    Messages:
    22
    Gender:
    Male
    Location:
    France
    So I've been through all of the errors and now everything looks clean :)

    But I'm not sure if I am going to keep this AI behavior because it cause some gameplay problems down the road.
    At least I've learned a lot and this is always valuable!

    Thank all of you for responding, and by the way, and thank you Leoreth for Dawn of Civilization I've had a lot of fun and good experiences with this mod.
     

Share This Page