• We are currently performing site maintenance, parts of civfanatics are currently offline, but will come back online in the coming days (this includes any time you see the message "account suspended"). For more updates please see here.

int CvTeam::getTechShareCount(int iIndex) const

vincentz

Programmer
Joined
Feb 4, 2009
Messages
3,614
Location
Denmark
Its been awhile since modding the gamecore, and I have been coding in Java, js, c#, html and css in between, so to say Im a bit rusty is an understatement ;), but I cant get the number of the project internet
upload_2018-12-22_21-31-50.png


I tried with int CvTeam::getTechShareCount(int iIndex) const but I always get 0... :(

I assume the iIndex is the number of the team.
So in a for loop:
for (int iI = 0; iI < MAX_PLAYERS; iI++)
I tried this:
getTechShareCount(GET_PLAYER((PlayerTypes)iI).getTeam())
but as mentioned, it always turn out to be 0 :(

Any help, would be much appreciated :)
 
I tried with int CvTeam::getTechShareCount(int iIndex) const but I always get 0... :(
The tech share code looks odd and it takes a moment to figure out. First of all the screenshot is written with:
PHP:
szBuffer.append(gDLL->getText("TXT_KEY_PROJECT_TECH_SHARE", kProject.getTechShare()));
kProject.getTechShare() returns an xml constant and it's obviously 2.

CvTeam::changeProjectCount() contains:
PHP:
if ((kProject.getTechShare() > 0) && (kProject.getTechShare() <= MAX_TEAMS))
{
    changeTechShareCount((kProject.getTechShare() - 1), iChange);
}
This will update m_aiTechShareCount[iIndex] and iIndex is kProject.getTechShare() - 1, or just plain 1. This means CvTeam::getTechShareCount(1) should return 1 if you have the project in question and 0 if not. All other indexes should always be 0 unless there are other projects in play.

CvTeam::updateTechShare(TechTypes eTech) consist of 3 parts.

The first finds the lowest iIndex for m_aiTechShareCount[iIndex], which is > 0. This will be stored as iBestShare = iIndex + 1.

The second part is a loop, which calculates iCount, which is the number of teams you have contact with, which have the tech in question.

Last part will grant the tech if iCount >= iBestShare.

This seems like an odd way to do things. First of all, why all those loops? The function seems to be executed for each tech. It's a horrible design. End the first loop when iBestShare is set because continuing the loop will not change iBestShare. In fact IBestShare could be cached in CvTeam and recalculated in changeTechShareCount(). That way there is no need for looping to get the number. Just calculate it again on load or save the cache. I prefer calculating on load as it avoids changing the savegame format, which in turn avoids breaking savegames or messing with avoiding breaking savegames.

Between loop 1 and 2, return if iBestShare is MAX_INT because in that case you aren't getting shared techs. No need to calculate how many owns the tech in question.

Last, end loop 2 once iCount == iBestShare. If you just need 2, there is no need to count if it is 2 or 17 teams. The result won't change.
 
Thanks :) Guess its bestshare i was looking for. In my mod I have several "internet" projects starting out with National library, which will give a bit (not the entire tech) if tech is shared with 8 civs. After that there is Encycplopedia with 6 civs. Then communication network (telephones/radios) with 4 and lastly the Internet with 2. If civ have contact & open borders the count adds one more.
However I want to limit the number of techs getting shared depending on the project. I did work a lot on it, but also remember it was hell to mod, but basically I want a (numberOfTechsGettingShare = (10 - ProjectCivs#), so the NatLib will give a bit of beakers to only 2 techs, while the ComNet will give to 6 techs.
Now, I have disabled updateTechShare() everywhere except for doTurn in Team.cpp(i didnt like the way the techs were shared with allies), and changed the code to give a little bit instead of entire tech.
Fun thing is, that when I made these changes (around 2 years ago i think) I did use bestshare to check for random, as well as how much were given, but Im terrible at commenting my own code ;)

Now the code looks like this (after adding a && (numberShares < (10 - iBestShare))) to my random check, and it seems to work, however looking at (my own old code) Im getting a bit confused, as it looks like it will distribute code to all civs??? (the last AllCivs loop in
updateTechShare(TechTypes eTech) seems overkill/wrong, and I cant remember why i did it)

Code:
int numberShares;

void CvTeam::updateTechShare(TechTypes eTech)
{
    int iBestShare;
    int iCount;
    int iI;

    if (isHasTech(eTech))
    {
        return;
    }

//Vincentz Techshare
    if (!GET_PLAYER(getLeaderID()).canResearch(eTech))
    {
        return;
    }
     
    iBestShare = MAX_INT;

    for (iI = 0; iI < MAX_TEAMS; iI++)
    {
        if (isTechShare(iI))
        {
            iBestShare = std::min(iBestShare, (iI + 1));
        }
    }

    if (iBestShare != MAX_INT)
    {
        iCount = 0;

        for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
        {
            if (GET_TEAM((TeamTypes)iI).isAlive())
            {
                if (GET_TEAM((TeamTypes)iI).isHasTech(eTech))
                {
                    if (isHasMet((TeamTypes)iI))
                    {
                        FAssertMsg(iI != getID(), "iI is not expected to be equal with getID()");
                        iCount++;
//Vincentz Techshare Start

                        if (isOpenBorders((TeamTypes)iI))
                        {
                            iCount++;
                        }
                    }
                }
            }
        }
/*        if (iCount >= iBestShare)
        {
            setHasTech(eTech, true, NO_PLAYER, true, true);
        }
*/
        if ((GC.getGameINLINE().getSorenRandNum((10+iBestShare), "Project Tech Sharing")) < (GC.getDefineINT("PROJECT_TECHSHARE_CHANCE"))
            && (numberShares < (10 - iBestShare))) //
        {
            int newProjectResearch = (getResearchCost(eTech) * iCount * GC.getGameINLINE().getSorenRandNum(10, "Project Tech Sharing") * GC.getDefineINT("PROJECT_TECHSHARE_MODIFIER"));
            newProjectResearch /= (MAX_PLAYERS * iBestShare * (GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getResearchPercent()));

            if (isHuman())
            {
                newProjectResearch *= (GC.getHandicapInfo(getHandicapType()).getNoTechTradeModifier());
                newProjectResearch /= 100;
            }
            if (newProjectResearch > 0)
            {
                for (int iI = 0; iI < MAX_PLAYERS; iI++)
                {
                    if (GET_PLAYER((PlayerTypes)iI).isAlive())
                    {
                        if (GET_PLAYER((PlayerTypes)iI).getTeam() == getID())
                        {
                            changeResearchProgress(eTech, (newProjectResearch), (PlayerTypes)iI);
//                            changeResearchProgress(eTech, (newProjectResearch), getID());
                            numberShares++;
                            CvWString szBuffer = gDLL->getText("TXT_KEY_GOT_RESEARCH_FROM_PROJECT", GC.getTechInfo(eTech).getTextKeyWide(), newProjectResearch);
                            gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PROJECT_COMPLETED", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_HIGHLIGHT_TEXT"));
                        }
                    }
                }
            }
        }
    }
}
//Vincentz Techshare End

void CvTeam::updateTechShare()
{
    int iI;
    numberShares = 0;//Vincentz Techshare

    for (iI = 0; iI < GC.getNumTechInfos(); iI++)
    {
        updateTechShare((TechTypes)iI);
    }
}
 
Last edited:
Back
Top Bottom