1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

What to do with CvGame::countCivTeamsEverAlive()

Discussion in 'Civ4 - Unofficial Patches' started by Dresden, Oct 19, 2008.

  1. Dresden

    Dresden Emperor

    Joined:
    Jul 10, 2008
    Messages:
    1,081
    This is a tough one. When looking back over the [3.17] Stock map scripts broken topic to see how ruff_hi fixed Team_Battleground and to check if other map scripts needed adjusting, I stumbled upon a big problem.

    The root cause of the map script breakage is that CvGame::countTeamTypesEverAlive() CvGame::countCivTeamsEverAlive() was drastically changed in 3.17 and appears to be pretty well broken. Using ruff's example of a game of 5 players where 2 are set to be on "Team1" and 3 are set to be on "Team 2", CvGame::countCivTeamsEverAlive() returns 5 :eek: when the same situation in previous versions of the game would return the expected 2.

    The old version (from Official 3.13):
    Spoiler :
    Code:
    int CvGame::countCivTeamsEverAlive() const
    {
    	int iCount;
    	int iI;
    
    	iCount = 0;
    
    	for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
    	{
    		if (GET_TEAM((TeamTypes)iI).isEverAlive())
    		{
    			iCount++;
    		}
    	}
    
    	return iCount;
    }
    


    The current version (from Official 3.17):
    Spoiler :
    Code:
    int CvGame::countCivTeamsEverAlive() const
    {
    	std::set<int> setTeamsEverAlive;
    
    	for (int iI = 0; iI < MAX_CIV_PLAYERS; iI++)
    	{
    		CvPlayer& kPlayer = GET_PLAYER((PlayerTypes) iI);
    		if (kPlayer.isEverAlive())
    		{
    			if (kPlayer.getParent() == NO_PLAYER)
    			{
    				setTeamsEverAlive.insert(iI);
    			}
    		}
    	}
    
    	return setTeamsEverAlive.size();
    }
    


    Now, I really want to fix this but there are 2 things in the way. First, knowing why they changed it the way they did. I don't want to simply revert to the old counting method unless I also account for whatever this change was supposed to fix. Based upon the use of getParent, I'm assuming that the idea was to not count any colonies since colony splitting is the only thing that assigns a parent. But nothing was obvious in the 3.17 Readme posted by Snoopy369 so I'm not sure; does anyone have any ideas on this?

    The second problem is unforseen consequences of the fix. This function is used by CvGame::getAdjustedLandPercent() to determine victory conditions like in Domination and it's exposed to Python. The former isn't so bad since the domination percentage is supposed to be higher with fewer teams so it would really be a bugfix. Using the 5civ/2team example the domination land goal would increase from 68 to 74% since 3 fewer teams will add 6%. But in terms of Python, people may have written code based on this buggy behavior and I'm not sure how big of an impact a fix would have.
     
  2. DanF5771

    DanF5771 Emperor

    Joined:
    Feb 21, 2008
    Messages:
    1,194
    I'm confused--was that just a typo?

    From Snoopy369's post of the 3.17 change log:
    I guess this is indeed the reason why they changed it.
    But yeah, I'm afraid they messed it up.
    Why introduce a set which collects all the distinct integers?
    I guess it should be fixed with:
    Code:
    [SIZE="4"]setTeamsEverAlive.insert(kPlayer.getTeam());[/SIZE]
    which returns the correct 2 for the 3/2-split example.
     
  3. Dresden

    Dresden Emperor

    Joined:
    Jul 10, 2008
    Messages:
    1,081
    Yeah, it's really countCivTeamsEverAlive(); damned long function names sometimes confuse me. ;)

    Good catch on the change log. I was looking for the word "team" to be somewhere in there and missed that one. :blush:

    I haven't a clue why they did that business with a set instead of using an integer counter like 3.13 had given what the loop looks like; although it would actually make sense if they had used kPlayer.getTeam() like you suggest. Since that changelog quote appears to verify the idea that they were trying to simply discount colonies, then this looks like the way to go. :thumbsup:

    One thing to note is that if you have a game with maximum players and some of them are killed off and replaced by colonies, the count still winds up wrong but (at least with the unmodified game) doesn't affect domination because at that point the 51% minimum has kicked in. 18 teams and 15 teams both result in the the same percentage.
     

Share This Page